我有一个存储为字符串的密钥,我正在尝试获取字符串的十六进制表示形式。我不想从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;
答案 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] << " ";
}
或者,如果您使用的是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] << " ";
}