繁体   English   中英

将unsigned char数组重建为unsigned long数组

[英]recasting a unsigned char array to an unsigned long array

好吧,我正在使用原始SHA1哈希来播种Mersenne Twister伪随机数生成器,生成器为我提供了使用无符号长整数或无符号长整数数组播种的选项

我正在使用的SHA1类将哈希值作为20字节的无符号字符数组

我想我可以将这个字符数组重新组合成一个长数组来获得一个有效的种子,但我怎么知道得到的long数组有多长?

示例代码:

CSHA1 sha1;
sha1.Update((unsigned char*)key, size_key);
sha1.Final();
unsigned char* hash;
sha1.GetHash(hash);

// Seed the random with the key
MTRand mt((unsigned long*)hash, <size of array of longs>);

我希望没有数据丢失(因为没有字节被丢弃),因为我需要保持加密安全

您可以使用len_of_chars * sizeof(char) / sizeof(long) ,其中len_of_chars大概为20。

你可以说

sizeof(unsigned long) / sizeof(unsigned char)

获得长的八位字节数。

然而,简单铸造有两个潜在的问题。

首先,字符数组可能没有正确对齐。 在某些处理器上,这会导致陷阱。 在其他方面,它只会减慢执行速度。

其次,如果程序必须在不同的架构上以相同的方式工作,那么您就会要求字节顺序问题。

您可以通过将字节显式复制到long数组来解决这两个问题。 未经测试的代码:

const int bytes_per_long = sizeof(unsigned long) / sizeof(unsigned char);
unsigned long hash_copy[key_length_in_bytes / bytes_per_long];
int i_hash = 0;
for (int i_copy = 0; i_copy < sizeof hash_copy / sizeof hash_copy[0]; i_copy++) {
  unsigned long b = 0;
  for (int i_byte = 0; i_byte < bytes_per_long; i_byte++)
    b = (b << 8) | hash[i_hash++];
  hash_copy[i_copy] = b;
}
// Now use hash_copy.

你的库似乎假定32位unsigned long s,所以你做同样的事情没有[更多]伤害。 实际上,我会尽可能地假设8位unsigned char ,甚至可能是两个未填充的小端表示。 所以你可以使用一个简单的强制转换(尽管我使用reinterpret_cast ),或者@ Gene的memcpy样本用于对齐。

但是,可移植代码*应该使用<cstdint> ,其中的uint#_t类型和分段,按值复制进行转换:

uint32_t littleEndianInt8sToInt32(uint8_t bytes[4]) {
    return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
}

......还有更好的名字。 对不起,这里来得晚了:)

*:当然,虽然stdint 本身不是非常便携(> = C ++ 11),并且不能保证精确宽度类型。 具有讽刺意味的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM