我正在寻找解决方案,该方法如何计算数据结构的哈希值。假设我们有一个这样的结构:
struct A
{
float64_t array[4][4];
float64_t x;
float64_t y;
uint8_t validationHash[32]; // here computed hash need to be stored
}
我也有函数Sha256(cont char * input, uint8_t (&output)[32])
,它作为参数接受输入和输出-计算出的哈希值。我知道我需要将每个值从结构转换为const char *。但是我的问题是下一步该怎么做,我应该为数组x和y中的每个值分别计算一个哈希值,然后将它们加在一起还是什么?
Sha256的实现与此处http://www.zedwood.com/article/cpp-sha256-function相同
您链接到的SHA-256哈希函数,就像大多数加密哈希实现一样,接受字节数组作为其输入。因此,第一步是对要散列的数据进行[[serialize。
这不像将结构转换为字节数组那样简单。序列化应该在操作系统和硬件之间可移植。系统之间结构的对齐方式,字节顺序等可能会有所不同,因此最好使用序列化库
,并将所有那些棘手的严格别名问题留给库作者。最佳选择:序列化库float64_t
类型),因此可以使用Boost序列化库。首先,创建一个序列化函数来指示Boost如何序列化A
:namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, A & a, const unsigned int version)
{
ar & a.array;
ar & a.x;
ar & a.y;
}
} // namespace serialization
} // namespace boost
然后,将其序列化为内存中的流:
std::ostringstream plaintext_buffer {}; { boost::archive::binary_oarchive oa(plaintext_buffer); oa << a; } std::string plaintext = plaintext_buffer.str();
现在您可以使用SHA-256哈希函数。我将把这一部分留给您练习。
plaintext.data()
代表数据,plaintext.size()
代表大小a.validationHash
struct A
{
double array[4][4];
double x;
double y;
uint8_t validationHash[32]; // here computed hash need to be stored
}
我稍微修改了这个答案:Serialize double and float with C,它声称是便携式IEEE 754串行器。凉!我将输出更改为内存缓冲区,替换为goto
,并将C类型转换转换为static_cast
。
void serializeIeee754(double x, uint8_t* destination) { int shift; unsigned long sign, exp, hibits, hilong, lowlong; double fnorm, significand; int expbits = 11; int significandbits = 52; if(x == 0) { /* zero (can't handle signed zero) */ hilong = 0; lowlong = 0; } else if(x > DBL_MAX) { /* infinity */ hilong = 1024 + ((1 << (expbits - 1)) - 1); hilong <<= (31 - expbits); lowlong = 0; } else if(x < -DBL_MAX) { /* -infinity */ hilong = 1024 + ((1 << (expbits - 1)) - 1); hilong <<= (31 - expbits); hilong |= (1 << 31); lowlong = 0; } else if(x != x) { /* NaN - dodgy because many compilers optimise out this test * isnan() is C99, POSIX.1 only, use it if you will. */ hilong = 1024 + ((1 << (expbits - 1)) - 1); hilong <<= (31 - expbits); lowlong = 1234; } else { /* get the sign */ if(x < 0) { sign = 1; fnorm = -x; } else { sign = 0; fnorm = x; } /* get the normalized form of f and track the exponent */ shift = 0; while(fnorm >= 2.0) { fnorm /= 2.0; shift++; } while(fnorm < 1.0) { fnorm *= 2.0; shift--; } /* check for denormalized numbers */ if(shift < -1022) { while(shift < -1022) { fnorm /= 2.0; shift++; } shift = -1023; } else { /* take the significant bit off mantissa */ fnorm = fnorm - 1.0; } /* calculate the integer form of the significand */ /* hold it in a double for now */ significand = fnorm * ((1LL << significandbits) + 0.5f); /* get the biased exponent */ exp = shift + ((1 << (expbits - 1)) - 1); /* shift + bias */ /* put the data into two longs */ hibits = static_cast<long>(significand / 4294967296); /* 0x100000000 */ hilong = (sign << 31) | (exp << (31 - expbits)) | hibits; lowlong = static_cast<unsigned long>(significand - hibits * 4294967296); } destination[0] = lowlong & 0xFF; destination[1] = (lowlong >> 8) & 0xFF; destination[2] = (lowlong >> 16) & 0xFF; destination[3] = (lowlong >> 24) & 0xFF; destination[4] = hilong & 0xFF; destination[5] = (hilong >> 8) & 0xFF; destination[6] = (hilong >> 16) & 0xFF; destination[7] = (hilong >> 24) & 0xFF; }
现在,您可以为写入到144字节缓冲区的A
编写自己的串行器:
void serializeA(A& a, uint8_t destination[144]) { uint8_t* out = destination; for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { serializeIeee754(a.array[i][j], out); out += 8; } } serializeIeee754(a.x, out); out += 8; serializeIeee754(a.y, out); }
然后将该缓冲区提供给您的哈希函数。