我需要散列输入字符串并产生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);
}
感谢您查看此问题。我感谢任何反馈!
答案 0 :(得分:0)
在上述评论的帮助下,我精心设计了以下解决方案:
public static UInt64 GetTruncatedMd5Hash(string input, int bitLength)
{
if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("input must not be null or whitespace");
if(bitLength > 64) throw new ArgumentException("bitLength must be <= 64");
var md5Hash = MD5.Create();
byte[] fullHashBytes = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
if(bitLength == 64)
return BitConverter.ToUInt64(fullHashBytes, 0);
var bitMask = (1UL << bitLength) - 1UL;
return BitConverter.ToUInt64(fullHashBytes, 0) & bitMask;
}
它比我之前尝试做的更紧凑(也更快)。