Crypto++ HexEncoder 无法始终如一地工作
Crypto++ HexEncoder not working consistently
这是我的代码
#include <cryptopp/hex.h>
#include <string>
#include <iostream>
void hexlify(CryptoPP::byte* bytes, std::string &hex_string, size_t size)
{
CryptoPP::StringSource ss(bytes, size, true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hex_string)));
}
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
CryptoPP::StringSource ss(hex_string, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)));
std::cout << decoded + "\n"; // For testing
bytes = (CryptoPP::byte*)decoded.data();
}
int main()
{
std::string seed = "BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60";
std::cout << "\n" + seed + "\n";
CryptoPP::byte* b;
unhexlify(seed, b);
std::string s;
hexlify(b, s, 32);
std::cout << s;
std::cout << "\n\n";
}
它应该采用 32 字节、64 字符的十六进制字符串 seed
,打印它,将其转换为字节,然后将其转换回十六进制字符串 (s
) 并打印.我还让它在 unhexlify
函数中打印解码后的字符串。
我的期望是输出如下所示:
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
第一行(seed
)和第三行(s
,seed转换成字节来回)应该是一样的。很少,这正是发生的事情。然而,大多数时候第一行和第三行是完全不同的。
奇怪的是我对代码做了零改动,甚至没有重新编译。但是每次我 运行 可执行文件时,它都会说一些不同的东西。更奇怪的是,每次我 运行 第三行都不一样。同样,即使我 运行 在不更改代码或重新编译的情况下使用相同的可执行文件,它也会发生。这是 5 运行s:
的输出
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC0AE8B7F0000AB7615AD06EA16A2889A960301000000189C960301000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205B40C2B87F0000AB7615AD06EA16A288FA9B060100000018FC9B0601000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC07DA67F0000AB7615AD06EA16A2885A6C0B01000000185C6C0B01000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC06EB47F0000AB7615AD06EA16A288DAAE090100000018DCAE0901000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC0F9EB7F0000AB7615AD06EA16A288DAF5010100000018DCF50101000000
第二行每次都是一样的,所以我知道问题出在 hexlify
函数 and/or Crypto++ HexEncoder 上。此外,AB7615AD06EA16A2
部分在 seed
和 s
中始终匹配。匹配的部分从第 17 个字符到第 32 个字符。这总是发生在我尝试的每一粒种子上。但其他一切通常都不同。
我不明白为什么它没有将字节正确编码为十六进制字符串。而且我不明白为什么即使我不对代码进行任何更改,它也很少起作用。而且我特别不明白每次 运行 相同的编译代码时输出会有什么不同。这是怎么回事?
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
CryptoPP::StringSource ss(hex_string, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)));
std::cout << decoded + "\n"; // For testing
bytes = (CryptoPP::byte*)decoded.data(); // <--
}
你 return 指向局部变量 decoded
拥有的缓冲区的指针,该变量在函数退出后消失。通过将悬挂指针传递给 hexlify
,您会得到未定义的行为。要解决问题 return 来自 std::string unhexlify(std::string hex_string)
的字符串并调用 hexlify(bytes.data(), s. bytes.size())
.
这个函数看起来很可疑:
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
// stuff added to decoded, maybe...
bytes = (CryptoPP::byte*)decoded.data();
}
decoded
是一个局部变量,它在函数退出时被销毁,但是你让 bytes
指向它的内部数据,导致悬空指针(这是未定义的行为,并由此解释了不同的输出。)
您应该 return 解码为 return 值(按值),并将其存储在调用者的堆栈中。然后在调用代码中此函数 returns 之后将字节设置为其数据。
这是我的代码
#include <cryptopp/hex.h>
#include <string>
#include <iostream>
void hexlify(CryptoPP::byte* bytes, std::string &hex_string, size_t size)
{
CryptoPP::StringSource ss(bytes, size, true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hex_string)));
}
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
CryptoPP::StringSource ss(hex_string, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)));
std::cout << decoded + "\n"; // For testing
bytes = (CryptoPP::byte*)decoded.data();
}
int main()
{
std::string seed = "BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60";
std::cout << "\n" + seed + "\n";
CryptoPP::byte* b;
unhexlify(seed, b);
std::string s;
hexlify(b, s, 32);
std::cout << s;
std::cout << "\n\n";
}
它应该采用 32 字节、64 字符的十六进制字符串 seed
,打印它,将其转换为字节,然后将其转换回十六进制字符串 (s
) 并打印.我还让它在 unhexlify
函数中打印解码后的字符串。
我的期望是输出如下所示:
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
第一行(seed
)和第三行(s
,seed转换成字节来回)应该是一样的。很少,这正是发生的事情。然而,大多数时候第一行和第三行是完全不同的。
奇怪的是我对代码做了零改动,甚至没有重新编译。但是每次我 运行 可执行文件时,它都会说一些不同的东西。更奇怪的是,每次我 运行 第三行都不一样。同样,即使我 运行 在不更改代码或重新编译的情况下使用相同的可执行文件,它也会发生。这是 5 运行s:
的输出BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC0AE8B7F0000AB7615AD06EA16A2889A960301000000189C960301000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205B40C2B87F0000AB7615AD06EA16A288FA9B060100000018FC9B0601000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC07DA67F0000AB7615AD06EA16A2885A6C0B01000000185C6C0B01000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC06EB47F0000AB7615AD06EA16A288DAAE090100000018DCAE0901000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC0F9EB7F0000AB7615AD06EA16A288DAF5010100000018DCF50101000000
第二行每次都是一样的,所以我知道问题出在 hexlify
函数 and/or Crypto++ HexEncoder 上。此外,AB7615AD06EA16A2
部分在 seed
和 s
中始终匹配。匹配的部分从第 17 个字符到第 32 个字符。这总是发生在我尝试的每一粒种子上。但其他一切通常都不同。
我不明白为什么它没有将字节正确编码为十六进制字符串。而且我不明白为什么即使我不对代码进行任何更改,它也很少起作用。而且我特别不明白每次 运行 相同的编译代码时输出会有什么不同。这是怎么回事?
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
CryptoPP::StringSource ss(hex_string, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)));
std::cout << decoded + "\n"; // For testing
bytes = (CryptoPP::byte*)decoded.data(); // <--
}
你 return 指向局部变量 decoded
拥有的缓冲区的指针,该变量在函数退出后消失。通过将悬挂指针传递给 hexlify
,您会得到未定义的行为。要解决问题 return 来自 std::string unhexlify(std::string hex_string)
的字符串并调用 hexlify(bytes.data(), s. bytes.size())
.
这个函数看起来很可疑:
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
// stuff added to decoded, maybe...
bytes = (CryptoPP::byte*)decoded.data();
}
decoded
是一个局部变量,它在函数退出时被销毁,但是你让 bytes
指向它的内部数据,导致悬空指针(这是未定义的行为,并由此解释了不同的输出。)
您应该 return 解码为 return 值(按值),并将其存储在调用者的堆栈中。然后在调用代码中此函数 returns 之后将字节设置为其数据。