【发布时间】:2014-02-21 23:35:12
【问题描述】:
我需要对输入字符串进行哈希处理并生成 14 位十进制数字作为输出。
math I am using 告诉我,我最多可以有一个 46 位无符号整数。
我知道 46 位 uint 意味着任何潜在的哈希函数的抗碰撞性更低。但是,我创建的哈希数将冲突概率保持在可接受的范围内。
如果社区能帮助我验证我将哈希截断为 46 位的方法是否可靠,我将不胜感激。我有一种直觉,有优化和/或更简单的方法可以做到这一点。我的函数如下(调用该函数时bitLength为46):
public static UInt64 GetTruncatedMd5Hash(string input, int bitLength)
{
var md5Hash = MD5.Create();
byte[] fullHashBytes = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
var fullHashBits = new BitArray(fullHashBytes);
// BitArray stores LSB of each byte in lowest indexes, so reversing...
ReverseBitArray(fullHashBits);
// truncate by copying only number of bits specified by bitLength param
var truncatedHashBits = new BitArray(bitLength);
for (int i = 0; i < bitLength - 1; i++)
{
truncatedHashBits[i] = fullHashBits[i];
}
byte[] truncatedHashBytes = new byte[8];
truncatedHashBits.CopyTo(truncatedHashBytes, 0);
return BitConverter.ToUInt64(truncatedHashBytes, 0);
}
感谢您查看此问题。感谢您提供任何反馈!
【问题讨论】:
-
您是否有必须使用截断字节的高位的规则?你想使用哪种字节序?小的?大的?还是根本不在乎?它是否需要跨 CPU 架构保持一致?
-
简单地使用
BitConverter.ToUInt64(fullHashBits, 0) % (1000000ul * 1000000ul * 100ul)怎么样?它使用原生字节序,因此如果您需要跨 CPU 架构的一致性,您需要 fixed endiannessbyte[]to integer converter。 -
或
BitConverter.ToUInt64(fullHashBytes.Reverse().ToArray(), 0) & 0x3fffffffffff; -
@CodesInChaos,感谢您的回复。在这种情况下,我追求的是小端。我不确定我是否理解在这种情况下使用高位和低位的后果。您能对此有所了解吗?
-
@L.B - 感谢您的建议。你的位掩码方法看起来很干净。
标签: c# hash byte bit-manipulation bitarray