代码之家  ›  专栏  ›  技术社区  ›  parkerchad81

将字符串从6位二进制解码为8位二进制

  •  2
  • parkerchad81  · 技术社区  · 7 年前

    基本上,我想解码这个:

    通过在消息生成时向每个字符添加0x40,一次将6位转换为可打印字符。下面的代码描述了将可打印值转换回二进制的过程。一旦字符串从可打印转换回二进制,就必须使用反向endian转换对其重新排序。

    收件人:

    0010 0100 0000 1000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1001 0001 1101 1010 0010 1001 0000 0000 1110 1111 0000 0100 0000 0000 0000 0000 0000 0000 0010 0000 0000 0000 1111 0011 1001 1111 0111 0111 1100 0100 0011 0011 0010 1110 0011 0011 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1110 1000 0000 0100 1111 0110 0000 0100 0000 0000 0000 0000 1100 0101 1110 0010 0111 1100 0101 1010 0101 0101 0111 0100 0000 0000

    用R表示:

    /*****************************************************************************/
    void Binary_Decode_6bit(char *in_string,unsigned char *out_string)
    {
        int i,j;
    
        /* DECODE string from 6 bit binary to 8 bit binary */
    
        /* Convert each 4 word group into 3 words */
        for (i=0, j = 0; i < strlen(in_string); i += 4)
        {
            out_string[j++] = ((in_string[i] &0x3f) << 2)   | ((in_string[i+1] &0x30) >> 4);
    
            out_string[j++] = ((in_string[i+1] &0x0f) << 4) | ((in_string[i+2] &0x3c) >> 2);
    
            out_string[j++] = ((in_string[i+2] &0x03) << 6) | (in_string[i+3] &0x3f);
        }
    }
    /****************************************************************************
    

    我希望使用R(甚至RCpp)函数来应用于这些消息的一个相当大的列表。

    感谢您的帮助!

    1 回复  |  直到 7 年前
        1
  •  3
  •   Ralf Stubner    7 年前

    您可以直接从Rcpp通过R导出的函数使用C++(井C)代码:

    #include <Rcpp.h>
    
    void Binary_Decode_6bit(char *in_string, unsigned char *out_string)
    {
      int i,j;
    
      /* DECODE string from 6 bit binary to 8 bit binary */
    
      /* Convert each 4 word group into 3 words */
      for (i=0, j = 0; i < strlen(in_string); i += 4)
      {
        out_string[j++] = ((in_string[i] &0x3f) << 2)   | ((in_string[i+1] &0x30) >> 4);
    
        out_string[j++] = ((in_string[i+1] &0x0f) << 4) | ((in_string[i+2] &0x3c) >> 2);
    
        out_string[j++] = ((in_string[i+2] &0x03) << 6) | (in_string[i+3] &0x3f);
      }
    }
    
    // [[Rcpp::export]]
    Rcpp::RawVector decode(std::string input) {
      if (input.size() % 4 != 0) 
        Rcpp::stop("input size must be a multiple of 4");
      std::vector<unsigned char> tmp(input.size() * 3 / 4);
      Binary_Decode_6bit(&input[0], &tmp[0]);
      Rcpp::RawVector result(tmp.size());
      std::copy(tmp.begin(), tmp.end(), result.begin());
      return result;
    }
    
    /*** R
    decode("I@`@@B@@@@@@@@@@@@@@@@@@@IGZJPCoA@@@@B@@|y}wqCLnLp@@@@@@z@SvA@@@q^I|VeUt@@@@")
    decode("I@`@@B@@@@@@@@@@@@@@@@@@@IGZJPCoA@@@@B@@|y}wqCLnLp@@@@@@z@SvA@@@q^I|VeUt@@@")
    */
    

    输出:

    > decode("I@`@@B@@@@@@@@@@@@@@@@@@@IGZJPCoA@@@@B@@|y}wqCLnLp@@@@@@z@SvA@@@q^I|VeUt@@@@")
     [1] 24 08 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 91 da 29 00 ef 04 00 00 00 20 00 f3 9f 77 c4 33
    [36] 2e 33 00 00 00 00 00 e8 04 f6 04 00 00 c5 e2 7c 5a 55 74 00 00 00
    
    > decode("I@`@@B@@@@@@@@@@@@@@@@@@@IGZJPCoA@@@@B@@|y}wqCLnLp@@@@@@z@SvA@@@q^I|VeUt@@@")
    Error in decode("I@`@@B@@@@@@@@@@@@@@@@@@@IGZJPCoA@@@@B@@|y}wqCLnLp@@@@@@z@SvA@@@q^I|VeUt@@@") : 
      input size must be a multiple of 4
    

    @ 在输入字符串的末尾获取所需的大小。我没有详细比较结果,但是对于我比较过的示例,你的二进制表示和我的十六进制表示是一样的。

    推荐文章