C#:如何生成短MD5代码?

时间:2009-08-09 14:12:35

标签: c# hash cryptography md5

当我使用MD5加密加密23时,我得到37693cfc748049e45d87b8c7d8b9aacd这个32个字符长的字符串,对于23来说总是静态的。

我想要相同类型的机制但是应该生成18个或更少(例如:122ff1e4883358b6)字符长字符串而不是32。

我如何在C#中做到这一点,c#??

中是否有更短版本的MD5

7 个答案:

答案 0 :(得分:30)

我喜欢@ RichieHindle的回答。但是,如果您有兴趣丢失较少的保真位(从而降低冲突风险),您可以获取MD5哈希返回的128位值,并使用ASCII85(也称为Base85)对其进行编码编码),而不是基于十六进制的编码。这将为您提供20个字节的整个哈希值(这比您想要的更多,但是您可以关闭2个字节,与使用十六进制编码删除的32个字节中的14个相比,所产生的损失要小得多。)

修改:Prashant说20个字符足够接近,并要求提供示例代码:

从MD5.ComputeHash调用中获取MD5哈希后,您可以使用Jeff Atwood's ASCII85 encoder

MD5 m = MD5.Create();
byte[] hash = m.ComputeHash(System.Text.Encoding.ASCII.GetBytes("23"));
Ascii85 encoder = new Ascii85();
encoder.EnforceMarks = false;
string hash85 = encoder.Encode(hash);
Console.Out.WriteLine(hash85);

产量

2ebDPFFZsD?&,r1fX\$,

所以你可以使用hash85encoder.EnforceMarks确保编码不包含与ASCII85关联的一些典型前缀和后缀。

答案 1 :(得分:10)

您可以根据需要获取尽可能多的MD5哈希值,然后将其余部分丢弃。所有位都具有相同的值,因此在执行此操作与使用本机产生较少位的散列算法之间没有区别。

(如果出于安全原因这样做,请记住,无论算法如何,更少的位都会使哈希更容易破解。即使在安全应用程序之外,更少的位也会增加冲突的风险。另外请记住,MD5是这些天相对不安全 - SHA-1或SHA-2被认为更安全。)

答案 2 :(得分:7)

MD5始终创建128位哈希值。

其他较小的Hashtypes(取自维基百科)

Fowler-Noll-Vo散列函数(32,64,128,256,512或1024位)
Jenkins哈希函数(32位)
MurmurHash(32或64位)
Pearson散列(8位)

但请记住hash collisions

答案 3 :(得分:4)

如果您希望能够将结果映射回其原始值而不发生冲突,我将不会使用哈希函数。

如果你的目标是将一个小的十进制数转换成一个长的混淆字符串,只需发明一些映射算法并用zBase32或类似的方法对结果进行编码。

public string Obfuscate(long x)
{
    return ToZBase32(BitConverter.GetBytes(x * 63498398L));
}

public long Deobfuscate(string x)
{
    return BitConverter.ToInt64(FromZBase32(x)) / 63498398L;
}

23被编码为"gmuyaiayyyyyy"。 (63498398由公平骰子选择。)

答案 4 :(得分:3)

使用FVNHash - http://www.codeproject.com/KB/security/FnvHash.aspx

您可以设置哈希的长度,出于安全原因不使用

答案 5 :(得分:3)

最短有用的哈希算法是md5。生成16个字节= 128位散列。如果你使用base 64编码...每个字节/ char有6个有用位。

你应该能够将md5减少到22个字符(ascii)。你有什么是十六进制版本,其中2个字节代表一个实际字节

(留下由b64引入的尾随填充)

还具有为合法文件名使用相同的附加优势。 (当然你将不得不用默认的/和+字符替换任何其他符号与你的操作系统的文件命名约定冲突。

base64(通过替换/和+)确保您的哈希不会使用特殊字符来破坏网址,这可能对您的网络服务器意味着什么

  

ASCII85添加了在用作文件名和网址时难以处理的字符

md5('此字符串将被散列')

'37aa3296c523f6c5a7fd2102a9155dcc'(hex)(32 bytes)

raw md5('此字符串将被哈希')

[55,170,50,150,197,35,246,197,167,253,33,2,169,21,93,204] =(16字节)

原始md5字符串的base64

N6oylsUj9sWn_SECqRVdzA ==

我最后的哈希

N6oylsUj9sWn_SECqRVdzA 这实际上是22个ascii字符中的完整md5

([你可以剥离两个尾随= md5总会有两个 - 稍后在解码时添加它们。还用b64中的+和/字符替换我喜欢的任何其他 - (破折号)和_(下划线)] < / p>

答案 6 :(得分:1)

这个32个字符的长字符串是十六进制的数字:0-f 你可以通过将其十六进制值转换为36:0-z

的基数来缩短它