When can a structure be hashed as an array of bytes?

For structures where equality means the identical most derived type and equality of bytes for each data item, when, if ever, can a structure be hashed as an array of bytes?

This document

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3333.html

under the heading "Hashing objects in the form of byte arrays" implies that structures with any addition cannot be hashed safely as an array of bytes.

Is it an explicit test for padding required for a secure hash of a structure as an array of bytes? Is it enough?

If so, does the following sketch fit this test?

#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; } 

If the structure has padding, is there a way around the path to allow hashing as an array of bytes, for example. zero fill bits?

“Safe” here means two structures that compare the same hash with the same values.

+6
source share
3 answers

Pretty much never. The standard does not define how inheritance is implemented. with vtable pointers, so there is no guarantee that two classes that have the same derived type will have any implementation-related data related to inheritance.

Also, since they are not PODs, bias is not guaranteed to work or produce meaningful results - I believe this is just plain UB.

Long and short, you should not try to consider structures as arrays of bytes, because they are not.

As for his intentions on paper, it is rather a concession to some of the frenzied "e-Maher speeches!" dogs on the committee, not the actual thing he wants to do.

+4
source

The document you referenced prety says a lot about requirements:

 is_trivially_copyable<T>::value && is_standard_layout<T>::value && is_contiguous_layout<T>::value 

which must have true recursion for the structure itself and all its members.

The first two checks are already included in the standard library, and you can implement is_contiguous_layout<T>::value yourself. As a basis, it should be enough to compare the sum of the sizes of its members with the size of the structure itself. I do not think offset verification is really necessary.

This, of course, should work on "regular" platforms ( CHAR_BIT == 8 , 2-complement), if your type consists only of integer types. I am not sure, however, if it also works with bools and floating point numbers, since I believe that the standard does not provide an unambiguous two-way comparison between the value of a variable and its representation in bits.

EDIT: I just realized that you cannot fulfill the condition of same most derived type if no elements are added to the derived class, or if you are comparing two different classes that have the same members. Therefore, you will have to consider the type separately.

+2
source

If the structure is POD, you should be able to simply bzero or memcpy for 0 for the entire structure during initialization, then hashing as an array of bytes should be good and efficient.

0
source

Source: https://habr.com/ru/post/984444/


All Articles