我有一个库使用 uint256_t
表示哈希值,另一个库使用 uint8_t
数组表示。
我猜应该有一种方法可以将 uint256_t
剪切/转换成 uint8_t[32]
。
但是,我还没有找到简单的转换方法。
我有一个库使用 uint256_t
表示哈希值,另一个库使用 uint8_t
数组表示。
我猜应该有一种方法可以将 uint256_t
剪切/转换成 uint8_t[32]
。
但是,我还没有找到简单的转换方法。
使用memcpy
。
你有两种不相关的类型,但你知道哈希的二进制表示对于两者都是相同的。在两种类型之间进行转换的最安全方式是通过memcpy
。
uint256_t source_hash;
// compute source_hash
// [...]
uint8_t dest_hash[32];
std::memcpy(dest_hash, &source_hash, 32);
memcpy
的转换之前,请务必仔细检查。std::bit_cast
,也可以用于此类转换,并且很可能会生成与基于调用memcpy
的解决方案完全相同的机器代码。如果您的编译器已经支持此功能,则可以选择bit_cast
,因为它在语法上类似于内置的C ++转换。std::bit_cast
不能用于将数据转换为数组,因为数组不能作为函数的返回类型。 - eerorikastd::array
,这个容器还有很多其他好处。 - underscore_dstd::bit_cast
(https://en.cppreference.com/w/cpp/numeric/bit_cast)。在此之前,标准和定义的方法是使用std::memcpy
:uint256_t msg = 1040449494439944;
uint8_t hash[32] = {};
std::memcpy(hash, &msg, sizeof(msg));
深入解释为什么在这种情况下调用reinterpret_cast
的是不好的,由Jason Turner提供。
uint256_t msg = 1040449494439944;
uint8_t* hash = (uint8_t*) &msg;
cout << sizeof(hash) << endl;
[无符号]字符
才是合法的,而uint8_t
不能保证是char
类型,尽管在实践中通常是这种情况。 - underscore_dreinterpret_cast<uint8_t*>
。 - underscore_d
reinterpret_cast<uint8_t*>(&value)
应该就足够了。 - HolyBlackCatstd::memcpy
代替。 - Resurrectionuint8_t
是一个char
类型定义,那么它就不是 UB。可以通过static_assert
来验证这一点。然而,确实std::bit_cast<>()
或者在 C++20 之前的std::memcpy()
版本通常是明确定义且更可取的 - 并且应该被优化为相同的代码。 - underscore_dunsigned char
typedef 的可能性几乎为零。如果失败了,你就去修复代码。 - HolyBlackCatreinterpret_cast
操作之前如何确保其有效性。但我更希望不要用这种方式来实现,正如我之前已经说过的那样。 - underscore_d