如何将字符串转换为十六进制表示形式

How do I convert a string into HEX representation?

本文关键字:十六进制 表示 转换 字符串      更新时间:2023-10-16

我有一个存储为字符串的键,我正在尝试获取字符串的十六进制表示形式。我不想从 ASCII 转换为十六进制。

std::string keyInStr = "1314191A1B";
unsigned char keyInHex[5];
for (int i = 0; i < 5; i++)
 {
   keyInHex[i] =   keyInStr[i];
   printf("%02X ", keyInHex[i]);
 }

电流输出: 31 33 31 34 31

预期输出:13 14 19 1A 1B

换句话说,这就是我想存储在数组中的内容。

keyInHex[0] = 0x13;
keyInHex[1] = 0x14;
keyInHex[2] = 0x19;
keyInHex[3] = 0x1A;
keyInHex[4] = 0x1B;

显示的string已经采用十六进制表示形式。您真正要求的是将该十六进制解码回其原始二进制数据,然后将该数据打印为十六进制。这是多余的。只需按原样打印string,每 2 个字符后插入一个空格,例如:

std::string keyInStr = "1314191A1B";
for (int i = 0; i < keyInStr.size(); i += 2)
{
   //printf("%.2s ", keyInStr.c_str()+i);
   std::cout << keyInStr.substr(i, 2) << " ";
}

否则,如果您打算实际使用密钥二进制数据,那么您确实需要解码字符串,例如:

unsigned char hex2dec(const std::string &s, size_t pos)
{
   char ch = s[pos];
   if (ch >= 'A' && ch <= 'F')
      return (ch - 'A') + 10;
   if (ch >= 'a' && ch <= 'f')
      return (ch - 'a') + 10;
   if (ch >= '0' && ch <= '9')
      return (ch - '0');
   // error!
}
unsigned char decodeHexByte(const std::string &s, size_t pos)
{
   return (hex2dec(s, pos) << 4) | hex2dec(s, pos+1);
}
std::string keyInStr = "1314191A1B";
unsigned char keyInHex[5] = {};
for (int i = 0, j = 0; i < 5; ++i, j += 2)
{
   keyInHex[i] = decodeHexByte(keyInStr, j);
   //printf("%02X ", keyInHex[i]);
   std::cout << std::hex << std::setw(2) << std::setfill('0') << (int) keyInHex[i] << " ";
}

现场演示

或者,如果您使用的是 C++11 或更高版本:

std::string keyInStr = "1314191A1B";
unsigned char keyInHex[5] = {};
for (int i = 0; i < 5; ++i)
{
   keyInHex[i] = std::stoi(keyInStr.substr(i*2, 2), nullptr, 16);
   //printf("%02X ", keyInHex[i]);
   std::cout << std::hex << std::setw(2) << std::setfill('0') << (int) keyInHex[i] << " ";
}

现场演示

当前输出对应于字符串中 ascii 字符的十六进制编码(0x31 表示 '1'0x33 表示 '3' 等...(。 这是正常的,因为您的代码只是每 char 复制一个输入字符:

keyInHex[i] =   keyInStr[i];    // output in hex is the same as input in ascii
如果要将输入

转换为十六进制,将两个输入数字组合成一个输出数字(例如 '1''3'产生一个对应于0x13的字节,您需要逐个迭代输入字符串,每次都采用相当于以 ASCII 表示的十六进制数字的二进制。

您可以通过将 ascii 十六进制数字转换为二进制数字来执行此操作:

 if (keyInStr[i]>='A') 
     digit =  keyInStr[i]-'A'+0x0A;  // assuming that uppercase only is used 
 else digit = keyInStr[i]-'0';  

然后,您可以将两个这样的数字与以下数字组合在一起:

keyInHex[j] = (digit1<<4) | digit2;     

或者,如果您在课程中尚未看到位运算:

keyInHex[j] = digit1*16 + digit2;

由于我不想做你的功课,所以我让你作为一个练习重写循环以处理 2 的数字。 注意:在最坏的情况下,上次迭代中可能存在一个孤立的数字。

keyInHex[i] = keyInStr[i]

如果您知道您的字符串包含一个字符数量为偶数的精确十六进制字符串,这将起作用:

std::string keyInStr = "1314191A1B";
std::vector<char> keyInHex;
for (size_t i = 0; i < keyInStr.length(); i += 2)
{
    std::string currentByte = keyInStr.substr(i, 2);
    keyInHex.push_back(static_cast<char>(std::strtol(currentByte.c_str(), NULL, 16)));
}
for (size_t i = 0; i < keyInHex.size(); i++)
{
    std::cout << std::hex << std::setw(2) <<  (keyInHex.at(i) & 0xFF) << " ";
}
我想

出了这个:

#include <iostream>
using namespace std;
int main()
{
    std::string keyInStr = "1314191a1b";
    const int SIZE = 5;
    unsigned char keyInHex[SIZE];
    unsigned long long hexVal = stoull(keyInStr, nullptr, 16);
    for (int i = 0; i < SIZE; i++)
     {
       keyInHex[i] = (hexVal >> ((SIZE - i - 1) * 8)) & 0xFF;
       printf("%02X ", keyInHex[i]);
     }
    return 0;
}

说你不想将 ASCII 转换为十六进制,但我想不出不涉及字符串到二进制数据转换的东西。从那里它只是移动位并做一个掩码。