将数据输入到十六进制表示的字符串流中



我试图通过字符串流提取十六进制的哈希摘要,但在迭代数据时无法使其工作。

使用std::hex,我可以很容易地使用普通整数文字来完成这项工作,比如:

#include <sstream>
#include <iostream>
std::stringstream my_stream;
my_stream << std::hex; 
my_stream << 100;
std::cout << my_stream.str() << std::endl; // Prints "64"

然而,当我尝试从摘要中推送数据时,它只是将数据解释为字符,并将它们推送到字符串流中。以下是功能:

#include <sstream>
#include <sha.h> // Crypto++ library required
std::string hash_string(const std::string& message) {
using namespace CryptoPP;
std::stringstream buffer;
byte digest[SHA256::DIGESTSIZE]; // 32 bytes or 256 bits
static SHA256 local_hash;
local_hash.CalculateDigest(digest, reinterpret_cast<byte*>(
const_cast<char*>(message.data())),
message.length());
// PROBLEMATIC PART
buffer << std::hex; 
for (size_t i = 0; i < SHA256::DIGESTSIZE; i++) {
buffer << *(digest+i);
}
return buffer.str();
}

类型byte只是unsigned char的typedef,所以我不明白为什么它不能正确输入。使用std::cout打印返回值会导致ASCI混乱的正常字符解释。为什么它在第一种情况下有效,而在第二种情况下无效?

示例:

std::string my_hash = hash_string("hello");
std::cout << hash << std::endl; // Prints: ",≥M║_░ú♫&Φ;*┼╣Γ₧←▬▲▼ºB^s♦3bôïÿ$"

首先,std::hex格式修饰符适用于整数,而不是字符。由于您正在尝试打印unsigned char,因此不会应用格式修饰符。您可以通过转换为int来解决此问题。在您的第一个示例中,它之所以有效,是因为文字100被解释为一个整数。如果将100替换为例如static_cast<unsigned char>(100),则将不再获得十六进制表示。

其次,std::hex是不够的,因为您可能希望将每个字符填充为2位十六进制值(即F应打印为0F(。您还可以通过应用格式修饰符std::setfill('0')std::setw(2)(reference,reference(来修复此问题。

应用这些修改,您的代码将如下所示:

#include <iomanip>
...
buffer << std::hex << std::setfill('0') << std::setw(2);
for (size_t i = 0; i < SHA256::DIGESTSIZE; i++) {
buffer << static_cast<int>(*(digest+i));
}

最新更新