我需要基於一個可變長度字符串生成一個哈希值,該字符串可以存儲在不超過16個字段(由於供應商要求)的字段中。是否有一個散列算法,在C#中產生64位散列大小?
我連接在一起正在通過C#腳本轉換傳遞的幾個字符串以計算哈希。我受到供應商的文件規範的約束,因爲散列的輸出不能超過16個。
有沒有人有任何建議?作爲例子,MD5算法的字符串轉換長度爲32.
我需要基於一個可變長度字符串生成一個哈希值,該字符串可以存儲在不超過16個字段(由於供應商要求)的字段中。是否有一個散列算法,在C#中產生64位散列大小?
我連接在一起正在通過C#腳本轉換傳遞的幾個字符串以計算哈希。我受到供應商的文件規範的約束,因爲散列的輸出不能超過16個。
有沒有人有任何建議?作爲例子,MD5算法的字符串轉換長度爲32.
加密函數的設計使得可以將輸出截斷爲某種大小,並且截斷的散列函數仍然是安全的加密散列函數。例如,如果將SHA-512輸出的前128位(16字節)應用於某些輸入,則前128位是與其他128位加密散列一樣強的加密散列。
解決方案是選擇一些加密散列函數 - SHA-256,SHA-384和SHA-512是不錯的選擇,truncate the output到128位(16字節)。
- 編輯 -
基於註釋的散列值一定,當編碼爲ASCII,超過16個字符的ASCI配合,解決的辦法是
如果您有16個字節存儲128位數字不是問題。將128位值存儲爲16字節值,而不是將16字節值存儲爲十六進制的32個字符的字符串。
作爲說明,我已經在數據庫中使用GUID/UUID字段來存儲MD5散列。雖然不再加密保護,128位的MD5哈希值是罰款校驗(和比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
請注意,我不顯示文件內容,因爲有一個很好的機會,它將包含「不可打印」字符。
你可以很容易地使用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;
}
有何評論?似乎很好...
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!");
}
我注意到這個問題比較老,但我確定有人會發現這個答案對它有價值。
我的建議是使用能夠使用8位到512位的Blake2b。如果沒有使用密鑰大小,則在這種情況下使用默認值「512」。 Blake2的默認值是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.
*/
希望這有助於!
16什麼?它是二進制還是文本? – 2010-12-02 22:09:23
理想情況下,它會是文本,因爲它會寫入平面文件。 – Matt 2010-12-02 22:16:28
平面文件不一定是文本。 – 2010-12-02 22:19:04