C++ 如何将uint256\u t转换/剪切为uint8\u t[]

C++ 如何将uint256\u t转换/剪切为uint8\u t[],c++,C++,我得到了一个库,它使用uint256\u t表示散列,另一个库使用uint8\u t数组表示散列 我想应该有办法把这个uint256\u t剪切/转换成uint8\u t[32] 然而,我还无法找到如何轻松地转换它。使用 您有两个不相关的类型,但您知道哈希的二进制表示形式对于这两个类型都是相同的。在两者之间转换的最安全方式是通过memcpy uint256_t source_hash; // compute source_hash // [...] uint8_t dest_hash[32];

我得到了一个库,它使用
uint256\u t
表示散列,另一个库使用
uint8\u t
数组表示散列

我想应该有办法把这个
uint256\u t
剪切/转换成
uint8\u t[32]

然而,我还无法找到如何轻松地转换它。

使用

您有两个不相关的类型,但您知道哈希的二进制表示形式对于这两个类型都是相同的。在两者之间转换的最安全方式是通过
memcpy

uint256_t source_hash;
// compute source_hash
// [...]

uint8_t dest_hash[32];
std::memcpy(dest_hash, &source_hash, 32);
请注意,这仅在二进制表示形式确实相同时才有效。例如,如果库A将散列存储在big-endian中,库B将散列存储在little-endian中,则需要更复杂的转换。对于散列,二进制表示形式很可能完全相同,但在编写基于
memcpy
的转换之前,请务必仔细检查


C++20添加了,它也可以用于这样的转换,并且很可能会在调用
memcpy
的基础上为解决方案生成相同的机器代码。如果编译器已经支持这个,你可能更喜欢<代码> BITYCAST ,因为它在语法上类似于内置C++的c++。然而,我不确定可能的影响

uint256_t msg = 1040449494439944;
uint8_t* hash =  (uint8_t*) &msg;
cout << sizeof(hash) << endl;
uint256\u t msg=10404494439944;
uint8_t*散列=(uint8_t*)&msg;

cout在C++20中,我们将为此使用
std::bit_cast
()。在此之前,标准和定义的方法将是使用
std::memcpy

uint256_t msg = 1040449494439944;
uint8_t hash[32] = {};
std::memcpy(hash, &msg, sizeof(msg));

深入解释为什么在本例中最终调用
reinterpret\u cast
c-cast
是不好的。

假设endianness不是问题,
reinterpret\u cast(&value)
应该足够了。@HolyBlackCat这就是UB。我建议改为使用
std::memcpy
。@如果
uint8\u t
char
typedef,则复活不是UB。人们可以先断言这一点。然而,事实上,或者在C++20之前,
std::memcpy()
版本是明确定义的,并且通常更可取-并且无论如何应该优化到相同的代码中。@下划线d,如果
static\u assert
失败怎么办?@Evg老实说,它不是
无符号字符
typedef的可能性几乎为零。如果失败了,你就去修改代码。它只是合法地重新解释其他对象,如<代码> [un[签署] ] char < />代码>和<>代码> uTI88t不能保证是<代码> char < /C++ >类型,尽管在实践中通常是这样的。(如果必须,并且您知道它是有效的)
reinterpret\u cast
从C++20开始,同样的逻辑可以用下划线更好地表达。@下划线\u d关于位\u cast的观点很好。我将把它添加到答案中。谢谢!我如何使用memcpy进行转换,你能给我一个例子吗?@user2524707为你添加了一个例子。@下划线\u d
std::位\u cast
不能用于转换因为数组不能是函数的返回类型,所以将t转换为数组。