以十六进制表示向字符串流输入数据
Inputting data to stringstream with hexadecimal representation
我正在尝试通过字符串流提取十六进制的哈希摘要,但在遍历数据时我无法让它工作。
使用 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
的类型定义,所以我不明白为什么输入不正确。使用 std::cout
打印 return 值会给出正常字符解释的 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));
}
我正在尝试通过字符串流提取十六进制的哈希摘要,但在遍历数据时我无法让它工作。
使用 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
的类型定义,所以我不明白为什么输入不正确。使用 std::cout
打印 return 值会给出正常字符解释的 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));
}