何时可以将结构安全地散列为字节数组
When can a struct safely be hashed as an array of bytes?
对于相等意味着每个数据成员的相同大多数派生类型和字节相等的结构,如果有的话,什么时候可以安全地将结构散列为字节数组?
本文件
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3333.html
在标题"将对象散列为字节数组"下,表明带有任何填充的结构不能安全地作为字节数组进行散列。
是否需要对填充进行显式测试才能将结构安全地散列为字节数组?这足够吗?
如果是,下面的草图是否恰当地说明了该测试?
#include <cstddef>
#include <iostream>
struct A
{
int i;
float f;
char c;
};
// hashing would start at offs_i (possibly hopping over a v-table) and end at
// offs_c + sizeof(char)
int main()
{
const std::size_t size_A = sizeof(A);
const std::size_t size_int = sizeof(int);
const std::size_t size_float = sizeof(float);
const std::size_t size_char = sizeof(char);
const std::size_t offs_i = offsetof(A, i);
const std::size_t offs_f = offsetof(A, f);
const std::size_t offs_c = offsetof(A, c);
bool padded = false;
if (offs_f != size_int)
padded = true;
else if (offs_c != size_int + size_float)
padded = true;
std::cout << "padded? " << std::boolalpha << padded << std::endl;
}
如果一个结构确实有填充,是否有任何方法可以变通,允许将哈希作为字节数组,例如将填充位清零?
这里的"安全"是指两个比较相等的结构将散列为相同的值。
几乎从来没有。该标准没有定义继承是如何实现的,例如使用vtable指针,因此不能保证两个派生类型相同的类具有任何特定于实现的继承相关数据。
此外,由于它们不是POD,offsetof不能保证工作或产生有意义的结果——我相信它实际上只是一个普通的UB。
总之,不要把结构当作字节数组,因为它们不是。
至于他在报纸上的意图,这更可能是对委员会中一些狂热的"er mah gerd表演!"狗的让步,而不是他想做的实际事情。
您之前引用的论文阐述了以下要求:
is_trivially_copyable<T>::value &&
is_standard_layout<T>::value &&
is_contiguous_layout<T>::value
对于结构本身和所有成员,必须递归地为true。
前两个检查已经是标准库的一部分,您可以自己实现is_contiguous_layout<T>::value
。作为基础,将其成员的大小之和与结构本身的大小进行比较就足够了。我不认为,检查偏移量实际上是必要的。
如果您的类型仅由整数类型组成,那么这当然应该适用于"常用"平台(CHAR_BIT == 8
,2-完成)。然而,我不确定它是否也适用于布尔值和浮点数,因为我相信该标准并没有要求在变量的值和它的位表示之间进行唯一的双向映射。
EDIT:我刚刚意识到,如果派生类中没有添加任何成员,或者比较碰巧具有相同成员的两个不同类,则不能保留条件of same most derived type
。因此,您必须单独说明类型。
如果结构是POD,那么在初始化时,您应该能够为整个结构将bzero或memcpy设置为0,那么作为字节数组进行哈希应该是很好且高效的。
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 基于字节数组生成静态范围整数值
- 将字节数组转换为带有字节序问题的指针
- 找到一种有效的方法,在 2 个巨大的缓冲区上执行 MAX,每字节字节
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- 字节数组初始化会导致 DirectX 崩溃
- 使用 swig 追加到字节数组
- C++ 替换字节数组中项的顺序
- QDataStream 读取和写入的字节数比 QFile::length() 报告要多
- 如何从保存在 Java 中C++的字节数组中读取数字?
- 如何通过libpq c api插入字节的数组
- i2c中的字节指针数组
- 以 C++ 为单位递增 16 字节字符数组
- new[] 一个包含构造函数的字节对象数组没有错,对吧?
- 创建未知长度的字节/字符数组
- 我如何将bitset转换为字节/uint8数组
- C++ <--> C# 修改字节编组数组
- 将m个字节的数组拆分为n个字节的块
- c++到c#:有3个元素的字节指针数组等于什么?