6字符短哈希算法

Isu*_*uru 10 c# hash md5 sha

我的目标是为一个字符串生成一个包含6个字符的短Hash字符串(可能包含字符[AZ] [az] [0-9]),该字符串长度为42个不区分大小写的字母数字字符.唯一性是关键要求.安全性或性能不是那么重要.

是否有一个特定的算法可以给出这个结果,或者我应该坚持截断MD5哈希或SHA-1哈希(就像在这个问题中一样)?如果是这样,碰撞的概率是多少?

ole*_*sii 17

你最好的选择是截断众所周知的哈希函数(MD5或SHA-family),因为这些算法在哈希值上具有统计上良好的均匀分布(并且还使用完整哈希而不仅仅是6个字符).

现在对碰撞概率进行一些计算

- Number of letters in English alphabet: 26
- Add capitals: 26
- Add numerics: 10
--------------

In total you get 26 + 26 + 10 = 62 characters. 

Now you have 6 places, which gives you 62^6 possible combinations.
That is 56.800.235.584 ~ 57 billion combinations. 
This is a space of possible hash values - N.
--------------
To compute collisions let's use the formula 

Pcollision = K^2 / 2N

Which is a very rough approximation of collision probability

现在让我们看一下表格中许多项目的结果表--K

# items     | Probability of collision
---------------------------------------
10          |  1.7 * 10^-9
100         |  1.7 * 10^-7
1K          |  1.7 * 10^-5
10K         |  1.7 * 10^-3
100K        |  0.17

此公式只能用于小K,但它表明在哈希表中给定100K条目时,大概有17%的碰撞几率.

链接

碰撞概率

  • 感谢您的指导性评论。但我认为您在表中计算了“Pcollision = K^2 / N”,而不是“Pcollision = K^2 / 2N”? (2认同)

Via*_*ukh 8

轻松哈希:)

private string Hash(string str)
{
    var allowedSymbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
    var hash = new char[6];

    for (int i = 0; i < str.Length; i++)
    {
        hash[i % 6] = (char)(hash[i % 6] ^ str[i]);
    }

    for (int i = 0; i < 6; i++)
    {
        hash[i] = allowedSymbols[hash[i] % allowedSymbols.Length];
    }

    return new string(hash);
}
Run Code Online (Sandbox Code Playgroud)

  • 该算法由于XOR这里的哈希[i%6] ^ str [i]`而具有高冲突率.OP声明输入字符串不区分大小写,对于az和AZ,所有字符的最高两位是相同的.即使您使用了所有正常的可打印ASCII字符(0x20-0x7e),前66位字符集的前两位仍然相同. (3认同)