2011-11-16 35 views
1

我有以下问题:我试图使用Crypto++来计算数据块的adler32校验和,但在转换byte [4]数组输出后得到错误的校验和到uint32_t。Crypto ++将Adler32摘要(字节数组)转换为uint32_t

此功能与CRC32工作得很好:

CryptoPP::CRC32 crc; 
byte digest[CryptoPP::CRC32::DIGESTSIZE]; 
crc.CalculateDigest(digest, (const byte*)pData.data(), pData.size()); 
uint32_t checksum = *(uint32_t*)digest; //this works fine 

但函数计算的Adler32返回一个无效的值:

CryptoPP::Adler32 adler; 
byte digest[CryptoPP::Adler32::DIGESTSIZE]; 
adler.CalculateDigest(digest, (const byte*)pData.data(), pData.size()); 
uint32_t checksum = *(uint32_t*)digest; //this returns a invalid value 

希望有人可以给我一个提示。

的Fabian格尔茨

回答

0

的问题是,你想要的这个代码没有:

uint32_t checksum = *(uint32_t*)digest; //this returns a invalid value 

此代码说读取摘要,如果它的形式举行了32位整数该CPU本地存储32位整数。但它不包含这一点。它包含一个4字节的数组,代表散列,但不是x86-CPU样式的整数。

试试这个:

uint32_t checksum = ntohl(*(uint32_t*)digest); 

这说来读取原始字节转换成整数,然后将它们转换为X86主机格式。

+0

我收到以下编译器错误:“未定义的引用到'ntohl @ 4'”使用mingw甚至强硬我包括winsock2.h。有没有其他的方式来做到这一点,没有额外的功能? – Fabian

+0

你可以这样做:'checksum = digest [0];校验<< = 8;校验和| =消化[1];校验<< = 8;校验和| =消化[2];校验<< = 8;校验和| =摘要[3];' –

+0

它也违反了C/C++标准。 punning使用一个指向字节(应该是1)与int(应该是4)对齐的指针。该值需要'memmov''d或'memcpy''d出来。 – jww

0

好吧,我发现crypto ++的adler32实现初始化s1 = 1;在adler32.h http://www.cryptopp.com/docs/ref/adler32_8h_source.html s2 = 0,但它应该是s1 = 0和s2 = 0.现在我所有的校验和是正确的,但我仍然不明白为什么cryto ++的实现是“错误的”。 greetz Fabian

+0

我认为这是因为校验和计算为'1 + d_1 + d_2 + ... + d_n'。如果您将初始值省略为1,则不会遵循Adler32算法。 – jww