我需要根据可变长度字符串生成一个Hash值,我可以将其存储在不超过16的字段中(由于供应商要求)。
我将几个正在通过C#脚本转换传递的字符串连接在一起,以便计算Hash。我受到供应商文件规范的限制,因为哈希的输出不能超过16。
有没有人有任何建议?例如,MD5算法的字符串转换长度为32。
答案 0 :(得分:7)
加密函数的设计使得您可以将输出截断为某种大小,并且截断的散列函数仍然是安全的加密散列函数。例如,如果将SHA-512输出的前128位(16字节)应用于某些输入,则前128位是加密哈希,与任何其他128位加密哈希一样强。
解决方案是选择一些加密哈希函数 - SHA-256,SHA-384和SHA-512是不错的选择 - truncate the output到128位(16字节)。
<强> - 编辑 - 强>
基于注释,当编码为ASCII时,哈希值必须符合16个ASCI字符,解决方案是
答案 1 :(得分:0)
如果您有16个字节存储128位数字不是问题。将128位值存储为16byte值,而不是将16字节值存储为HEX的32个字符串。
作为注释,我在数据库中使用了GUID / UUID字段来存储MD5哈希值。虽然不再具有加密安全性,但128位MD5哈希对于Checksums来说很好(并且比64位好得多。)
var result = MD5.Create().ComputeHash(new byte[] { 0 });
Console.WriteLine(result.Length);
Console.WriteLine(Convert.ToBase64String(result));
Console.WriteLine(result.Aggregate(new StringBuilder(),
(sb, v) => sb.Append(v.ToString("x2"))));
//16
//k7iFrf4NoInN9jSQT9WfcQ==
//93b885adfe0da089cdf634904fd59f71
File.WriteAllBytes("tempfile.dat", result);
var input = File.ReadAllBytes("tempfile.dat");
Console.WriteLine(input.Length);
Console.WriteLine(Convert.ToBase64String(input));
Console.WriteLine(input.Aggregate(new StringBuilder(),
(sb, v) => sb.Append(v.ToString("x2"))));
//16
//k7iFrf4NoInN9jSQT9WfcQ==
//93b885adfe0da089cdf634904fd59f71
请注意,我没有显示文件内容,因为它很可能包含“不可打印”字符。
答案 2 :(得分:0)
您可以轻松地使用MD5哈希,但您必须改变它的存储方式。 MD5是128位,通常显示为32个4位(十六进制)值。但标准字符是8位,因此16个字符足以存储MD5哈希值。
要转换它,请尝试以下操作:
String hash32 = "d41d8cd98f00b204e9800998ecf8427e"
String hash16 = ""
for(int i = 0; i < 32; i+=2)
{
uint high = Convert.ToUInt32(hash32[i], 16);
uint low = Convert.ToUInt32(hash32[i+1], 16);
char c = (char) ((high << 4) | low);
hash16 += c;
}
答案 3 :(得分:0)
有关此代码的任何评论?似乎运作良好......
var p = new MD5CryptoServiceProvider();
var dic = new Dictionary<long, string>();
for (var i = 0; i < 10000000; i++)
{
if (i%25000 == 0)
Console.WriteLine("{0:n0}", i);
var h = p.ComputeHash(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
var b = BitConverter.ToInt64(h, 0);
// "b" is hashed Int64
if (!dic.ContainsKey(b))
dic.Add(i, null);
else
throw new Exception("Oops!");
}
答案 4 :(得分:0)
我注意到这个问题比较陈旧,但我确信有人会觉得这个答案很有价值。
我的建议是使用能够使用8位到512位的Blake2b。如果没有使用密钥大小,则使用默认值&#34; 512&#34;在这种情况下。 Blake2s默认值为256位。
// BLAKE2b
// using System.Data.HashFunction;
//
// String message to use.
string str = "The quick brown fox jumps over the lazy dog";
// Initialize
System.Data.HashFunction.Blake2B Blake2B = new System.Data.HashFunction.Blake2B();
// Get string hash bytes; create 64 bit hash.
var HashBytes = Blake2B.ComputeHash(str, 64);
// Convert bytes to string and remove the dashes.
string hexString = BitConverter.ToString(HashBytes).Replace("-", string.Empty);
// Display results.
MessageBox.Show(hexString);
/*
* "The quick brown fox jumps over the lazy dog" produces a hash value of
* "A8ADD4BDDDFD93E4877D2746E62817B116364A1FA7BC148D95090BC7333B3673F82401CF7AA2E4CB1ECD90296E3F14CB5413F8ED77BE73045B13914CDCD6A918"
* and "2FD0F3FB3BD58455" hash for 64 bits.
*/
希望这有帮助!