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

时间:2018-09-28 15:27:25

标签: r decode rcpp

我希望基于我拥有的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 0000 1110 1000 0000 0100 1110000 0110 0000 0100 0000 0000 0000 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 个答案:

答案 0 :(得分:3)

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

.ToString()

输出:

#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 ,以获取所需的大小。我没有详细比较结果,但是对于示例,我已经比较了您的二进制表示形式和十六进制表示形式。