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

R decode string from 6 bit binary to 8 bit binary

我正在寻找基于我拥有的 C++ 片段编写等效的 R 函数。见下文:

本质上,我想解码这个:

I@`@@B@@@@@@@@@@@@@@@@@@@IGZJPCoA@@@@B@@|y}wqCLnLp@@@@@@z@SvA@@@q^I|VeUt@@@

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

收件人:

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)函数来应用这些消息的相当大的列表。

感谢任何帮助!

您可以直接从通过 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

请注意,我在输入字符串的末尾添加了一个额外的 @ 以获得所需的大小。我没有详细比较结果,但是对于我比较过的示例,您的二进制表示与我的十六进制表示相同。