【问题标题】:Convert char array to byte array将字符数组转换为字节数组
【发布时间】:2021-03-16 17:08:07
【问题描述】:

我有一个这样声明的字符串。

CHAR bkp[40] = "dc74699a8381da395f10b"; <- this value comes from querying a registry value

在内存中(使用 VS 内存窗口)我看到了..

0x00000071432FF918 64 63 37 34 36 39 39 61 38 33 38 31 64 61 33 39 35 66 31 30 62 00 .. .. .. ..

我正在尝试将字符串转换为内存,以便在检查该内存地址时看到..

0x00000071432FF918 dc 74 69 9a 83 81 da 39 5f 10 0b .. .. .. ..

我的项目使用 C++,但该函数要求它返回到 char *。所以如果char数组需要转换成C++字符串也可以。

【问题讨论】:

  • 不清楚你在问什么,因为术语“字符数组”和“字节数组”在 C 中是可以互换的
  • C 还是 C++?选一个。然后专门定义“字节数组”,即您的意思是要查看字符串而不是组成它的 ASCII 字节,还是想要一些 std::byte 的容器,或者什么。
  • 看起来他们希望将字母数字序列视为十六进制序列。
  • printf("%02x", bkp[0]); 将打印64printf("%c", bkp[0]) 将打印 d
  • VS 在查看变量时有一个“十六进制显示”选项。是一样的数据。只是它的显示方式发生了变化。你问的是这个吗?

标签: c++ c


【解决方案1】:

只需遍历字符串,对于每个 2 字符对,您可以进行一些非常简单的计算和位移来提取字节值。例如:

BYTE decodeHex(char c)
{
    if (c >= '0' && c <= '9')
        return c - '0';
    else if (c >= 'A' && c <= 'F')
        return (c - 'A') + 10;
    else if (c >= 'a' && c <= 'f')
        return (c - 'a') + 10;
    else
        // illegal! throw something...
}

CHAR bkp[] = "dc74699a8381da395f100b";
int slen = strlen(bkp);

BYTE *bytes = new BYTE[slen / 2];
int blen = 0;

for(int i = 0; i < slen; i += 2)
{
    bytes[blen++] = (decodeHex(bkp[i]) << 4) | decodeHex(bkp[i+1]);
}

// use bytes up to blen as needed...

delete[] bytes;

【讨论】:

  • @TedLyngmo 感谢更新,我忘了+10
【解决方案2】:

您需要将字符数组转换为二进制文件。你的输入数组是一个十六进制字符串,所以这是相当简单的。

unsigned char toBinary(char c)
{
    if (c >= '0' && c <= '9')
        return c - '0';

    return (c - 'a') + 10;
}

CHAR bkp[40] = "dc74699a8381da395f10b"
unsigned char b[20];

int bi = 0;
for(int i = 0; i < 40; i += 2)
{
    char c = bkp[i];
    unsigned char v = toBinary(bkp[i]) << 4;
    v += toBinary(bkp[i+1])

    b[bi++] = v;
}

【讨论】:

    【解决方案3】:

    数组是一个字符串,所以你必须将字符转换为十六进制。 让我们使用老式的方法:

    const unsigned int length = sizeof(bkp);
    const std::string hex_digits = "0123456789abcdef";
    std::vector<uint8_t> destination;
    for (unsigned int index = 0U; index < length; index += 2U)
    {
        uint8_t byte_value = 0;
        std::string::size_type  position = hex_digits.find(bkp[index]);
        if (position == std::string::npos)
        {
           std::cerr << "invalid hex value at position " << index << "\n";
           break;
        }
        byte_value = position;
        ++index;
        position = hex_digits.find(bkp[index]);
        if (position == std::string::npos)
        {
           std::cerr << "invalid hex value at position " << index << "\n";
           break;
        }
        byte_value = (byte_value * 256) + position;
        destination.push_back(byte_value);
    }
    

    注意:上面的代码使用了 C++ 特性,因为原帖被标记为 C++。

    【讨论】:

      【解决方案4】:

      只是为了好玩,您可以使用非条件操作执行转换。

      一般:

      • 'A' = 64, 'a' = 96,两者都设置了第 6 位(值 64 十进制)
      • '0' = 48,因此没有设置第 6 位。

      您可以取输入,取低 4 位给我们 0->9、A->F 或 a->f,然后取第 6 位并将其用作乘数,以在需要时加上 +10 .

      #include <conio.h>
      #include <stdio.h>
      #include <string.h>
      
      void HexStrToRaw(char* in, unsigned char* out)
      {
          for (int loop = 0, o_loop = 0; loop < strlen(in); loop += 2, o_loop++)
          {
              out[o_loop] = (((in[loop] & 15) + ((in[loop] >> 6) * 9)) << 4) | ((in[loop + 1] & 15) + ((in[loop + 1] >> 6) * 9));
          }
      }
      
      int main(int argc, char** argv)
      {
          char          in[40] = "dc74699a8381da395f10b";
          unsigned char out[20];
      
          HexStrToRaw(in, out);
          for (int loop = 0; loop < sizeof(out); loop++)
          {
              printf("%d -> 0x%02x\n", loop, out[loop]);
          }
          return 0;
      }
      

      输出变成:

      0 -> 0xdc
      1 -> 0x74
      2 -> 0x69
      3 -> 0x9a
      4 -> 0x83
      5 -> 0x81
      6 -> 0xda
      7 -> 0x39
      8 -> 0x5f
      9 -> 0x10
      10 -> 0xb0
      11 -> 0xcc
      12 -> 0xcc
      13 -> 0xcc
      14 -> 0xcc
      15 -> 0xcc
      16 -> 0xcc
      17 -> 0xcc
      18 -> 0xcc
      19 -> 0xcc
      

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 1970-01-01
        • 2021-11-11
        • 1970-01-01
        • 1970-01-01
        • 2021-07-09
        • 1970-01-01
        相关资源
        最近更新 更多