当我使用MD5加密加密23
时,我得到37693cfc748049e45d87b8c7d8b9aacd
这个32个字符长的字符串,对于23来说总是静态的。
我想要相同类型的机制但是应该生成18个或更少(例如:122ff1e4883358b6
)字符长字符串而不是32。
我如何在C#中做到这一点,c#??
中是否有更短版本的MD5答案 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\$,
所以你可以使用hash85
。 encoder.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添加了在用作文件名和网址时难以处理的字符
'37aa3296c523f6c5a7fd2102a9155dcc'(hex)(32 bytes)
[55,170,50,150,197,35,246,197,167,253,33,2,169,21,93,204] =(16字节)
N6oylsUj9sWn_SECqRVdzA ==
我最后的哈希
N6oylsUj9sWn_SECqRVdzA 这实际上是22个ascii字符中的完整md5
([你可以剥离两个尾随= md5总会有两个 - 稍后在解码时添加它们。还用b64中的+和/字符替换我喜欢的任何其他 - (破折号)和_(下划线)] < / p>
答案 6 :(得分:1)
这个32个字符的长字符串是十六进制的数字:0-f 你可以通过将其十六进制值转换为36:0-z
的基数来缩短它