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

时间:2019-02-06 19:18:05

标签: c++

我有一个存储为字符串的密钥,我正在尝试获取字符串的十六进制表示形式。我不想从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;

4 个答案:

答案 0 :(得分:0)

当前输出对应于字符串中ascii字符的十六进制编码(0x31'1'0x33'3'等)。这是正常现象,因为您的代码仅将输入的一个字符复制为一个字符:

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]

答案 1 :(得分:0)

如果您知道您的字符串包含精确的十六进制字符串,其中包含偶数个字符,则可以使用:

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) << " ";
}

答案 2 :(得分:0)

我想到了这个

#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转换为十六进制,但是我想不出没有涉及字符串到二进制数据转换的内容。从那里开始,它只移动位并做一个掩码。

答案 3 :(得分:0)

显示的string已经 以十六进制表示。您真正需要的是将十六进制解码回其原始二进制数据,然后将该数据打印为十六进制。这是多余的。只需照原样打印string,在第二个字符后插入一个空格即可,例如:

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] << " ";
}

Live Demo

或者,如果您使用的是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] << " ";
}

Live Demo