我正在编写一个函数来散列字符串并以十六进制格式获取结果。 我得到的输出看起来与预期几乎相同,但由于缺少零而更短:
64: ae6a9df8bdf4545392e6b1354252af8546282b49033a9118b12e9511892197c6
64: ae6a9df8bdf4545392e6b1354252af8546282b4933a9118b12e9511892197c6
这是我的代码:
#include <openssl/evp.h>
#include <cstdint>
#include <array>
#include <string_view>
#include <charconv>
#include <iostream>
int main(){
std::string oceanic = "oceanic 815";
EVP_MD_CTX *context = EVP_MD_CTX_new();
EVP_DigestInit(context, EVP_sha256());
EVP_DigestUpdate(context, oceanic.data(), oceanic.size());
std::array<uint8_t, EVP_MAX_MD_SIZE> hash{};
unsigned int written = 0;
EVP_DigestFinal(context, hash.data(), &written);
std::cout << written << '/' << EVP_MAX_MD_SIZE << '\n';
// from https://emn178.github.io/online-tools/sha256.html
std::string_view expected = "ae6a9df8bdf4545392e6b1354252af8546282b49033a9118b12e9511892197c6";
std::cout << expected.size() << ": " << expected << '\n';
std::array<char, 64> hex{};
for (size_t iHash = 0, iHex = 0; iHash < written; ++iHash)
{
std::to_chars(&hex[iHex], &hex[iHex + 2], hash[iHash], 16);
iHex += 2;
// This also produces invalid result
// const char hexMap[] = "0123456789ABCDEF";
// const char ch = hash[iHash];
// hex[iHash] = hexMap[(ch & 0xF0) >> 4];
// hex[iHash + 1] = hexMap[ch & 0xF];
// iHash += 2;
}
std::cout << hex.size() << ": " << std::string_view(hex.data(), hex.size()) << '\n';
return 0;
}
https://godbolt.org/z/hq9onW49z
我不想使用
std::stringstream
因为我不需要动态分配。我在这里做错了什么?
对于使用十六进制表的第二个解决方案(已注释掉),我发现了错误。我为
hex[]
使用了无效的迭代器。
正确版本:
std::array<char, 64> hex{};
for (size_t iHash = 0, iHex = 0; iHash < written; ++iHash, iHex += 2)
{
constexpr const char hexMap[] = "0123456789abcdef";
const char ch = hash[iHash];
hex[iHex] = hexMap[(ch & 0xF0) >> 4];
hex[iHex + 1] = hexMap[ch & 0x0F];
}