【问题标题】:R decode string from 6 bit binary to 8 bit binaryR将字符串从6位二进制解码为8位二进制
【发布时间】:2018-09-28 15:27:24
【问题描述】:

我正在寻找基于我拥有的 C++ sn-p 编写一个等效的 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)函数来应用到相当大的这些消息列表。

感谢任何帮助!

【问题讨论】:

  • 那么你的问题是什么?到目前为止,您尝试过什么?
  • 我需要通过制定的流程将字符串转换为二进制并将其转换为十进制值。我只对编码/解码数据有过了解。我真的在寻找如何解决这个问题的方向。

标签: r decode rcpp


【解决方案1】:

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

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

【讨论】:

  • 太棒了!这是我想做的,也是一个好的开始。额外的“@”不应引起问题。现在我需要弄清楚如何使用反向字节序转换。
猜你喜欢
  • 2018-06-17
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2018-09-15
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
相关资源
最近更新 更多