C#:如何生成简短的 MD5 代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1251463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: How to generate short MD5 code?
提问by Prashant
When I am encrypting 23
using MD5 encryption I am getting 37693cfc748049e45d87b8c7d8b9aacd
this 32-character long string which will always be static for 23.
当我23
使用 MD5 加密进行加密时,我得到了37693cfc748049e45d87b8c7d8b9aacd
这个 32 个字符的长字符串,它对于 23 来说始终是静态的。
I want the same kind of mechanism but that should generate 18 or less (like: 122ff1e4883358b6
) characters long string instead 32.
我想要相同类型的机制,但应该生成 18 个或更少(如:)122ff1e4883358b6
字符的长字符串而不是 32 个。
How I can do that in C#, is there any shorter version of MD5 in c#??
我如何在 C# 中做到这一点,在 C# 中是否有更短版本的 MD5??
采纳答案by Blair Conrad
I like @RichieHindle's answer. However, if you're interested in losing fewer bits of fidelity (and thereby decreasing the risk of collisions), you could take the 128 bit value returned by the MD5 Hash, and encode it using ASCII85(also known as Base85 encoding), instead of a hexadecimal-based encoding. This will give you the whole hash in 20 bytes (which is more than you wanted, but you could chop 2 bytes off, resulting in much less loss than removing 14 of the 32 bytes you'd get using hex encoding).
我喜欢@RichieHindle 的回答。但是,如果您有兴趣减少保真度的损失(从而降低冲突的风险),您可以采用 MD5 哈希返回的 128 位值,并使用ASCII85(也称为 Base85 编码)对其进行编码,而不是基于十六进制的编码。这将为您提供 20 个字节的整个散列(这比您想要的要多,但您可以砍掉 2 个字节,从而比使用十六进制编码删除 32 个字节中的 14 个字节的损失要少得多)。
Edit:Prashant says 20 characters is close enough, and asked for sample code:
编辑:Prashant 说 20 个字符足够接近,并要求提供示例代码:
After obtaining the MD5 hash from the MD5.ComputeHash call, you can use Jeff Atwood's ASCII85 encoder:
从 MD5.ComputeHash 调用获得 MD5 哈希后,您可以使用Jeff Atwood 的 ASCII85 编码器:
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);
Yields
产量
2ebDPFFZsD?&,r1fX$,
so you can just use hash85
. The encoder.EnforceMarks
makes sure that the encoding doesn't include some typical prefix and suffixes that are associated with ASCII85.
所以你可以使用hash85
. 将encoder.EnforceMarks
可确保编码不包括与ASCII85相关的一些典型的前缀和后缀。
回答by Henrik P. Hessel
MD5 always creates a 128 Bit Hash.
MD5 总是创建一个 128 位的哈希。
Other smaller Hashtypes (taken from Wikipedia)
其他较小的哈希类型(取自维基百科)
Fowler-Noll-Vo hash function (32, 64, 128, 256, 512, or 1024 bits)
Jenkins hash function (32 bits)
MurmurHash (32 or 64 bits)
Pearson hashing (8 bits)
Fowler-Noll-Vo 哈希函数(32、64、128、256、512 或 1024 位)
Jenkins 哈希函数(32 位)
MurmurHash(32 或 64 位)
Pearson 哈希(8 位)
But remember hash collisions
但请记住哈希冲突
回答by RichieHindle
You can just take as much of the MD5 hash as you need, and throw the rest away. All the bits have equal value, so there's no difference between doing that and using some hashing algorithm that natively produces fewer bits.
您可以根据需要获取尽可能多的 MD5 哈希值,然后将其余的扔掉。所有位都具有相等的值,因此这样做与使用一些本机产生较少位的散列算法之间没有区别。
(If you're doing this for security reasons, remember that fewer bits makes hashes easier to crack, regardless of the algorithm. Even outside of security applications, fewer bits increase the risk of collisions. Also bear in mind that MD5 is relative insecure these days - SHA-1 or SHA-2 are considered more secure.)
(如果您出于安全原因这样做,请记住,无论算法如何,较少的位会使散列更容易破解。即使在安全应用程序之外,较少的位也会增加冲突的风险。另外请记住,MD5 是相对不安全的这些天 - SHA-1 或 SHA-2 被认为更安全。)
回答by dr. evil
Use FVNHash - http://www.codeproject.com/KB/security/FnvHash.aspx
使用 FVNHash - http://www.codeproject.com/KB/security/FnvHash.aspx
You can set the length of your hash, do not use it for security reasons.
您可以设置散列的长度,出于安全原因不要使用它。
回答by dtb
I wouldn't use a hash function if you want to be able to map the result back to its original value without collisions.
如果您希望能够将结果映射回其原始值而不会发生冲突,我不会使用哈希函数。
If your aim is to turn a small decimal number into a long obfuscated string, just invent some mapping algorithm and encode the result with zBase32or similar.
如果您的目标是将一个小的十进制数转换为一个长的混淆字符串,只需发明一些映射算法并使用zBase32或类似方法对结果进行编码。
public string Obfuscate(long x)
{
return ToZBase32(BitConverter.GetBytes(x * 63498398L));
}
public long Deobfuscate(string x)
{
return BitConverter.ToInt64(FromZBase32(x)) / 63498398L;
}
23
gets encoded to "gmuyaiayyyyyy"
. (63498398 chosen by fair dice roll.)
23
被编码为"gmuyaiayyyyyy"
. (63498398 通过公平掷骰子选择。)
回答by Anwar Chandra
this 32-character long string are number from hexadecimal : 0-f you can make it shorter by converting its hexadecimal value to radix of 36 : 0-z
这个 32 个字符的长字符串是十六进制的数字:0-f 您可以通过将其十六进制值转换为 36 的基数来缩短它:0-z
回答by geekay
shortest useful hash algorithm would be md5 . generates 16 bytes=128 bit hash. if you use base 64 encoding ...that is 6 useful bits per byte/char.
最短的有用哈希算法是 md5 。生成 16 字节 = 128 位哈希。如果您使用 base 64 编码......即每字节/字符 6 个有用的位。
u should be able to reduce the md5 to 22 characters (ascii). what you have is hex version where 2 bytes represent one actual byte
你应该能够将 md5 减少到 22 个字符(ascii)。您拥有的是十六进制版本,其中 2 个字节代表一个实际字节
(leaving the trailing padding introduced by b64)
(留下 b64 引入的尾随填充)
with an added advantage of using the same for legal filenames. (ofcourse u will have to substitute the default / and + characters with any other symbol which does not clash with file naming convention of your os.
使用相同的合法文件名的额外优势。(当然,您必须用任何其他不与您的 os.文件命名约定冲突的符号替换默认的 / 和 + 字符。
base64 (by replacing / and +) ensures your hash doesnot mess up the url with special characters which may mean something else to your webserver
base64(通过替换 / 和 +)确保您的哈希不会用特殊字符弄乱 url,这可能对您的网络服务器意味着其他东西
ASCII85 adds characters which are difficult to deal with when using as filenames and in urls
ASCII85 添加了在用作文件名和 url 时难以处理的字符
md5 ('This string will be hashed')
md5 ('这个字符串将被散列')
'37aa3296c523f6c5a7fd2102a9155dcc' (hex) (32 bytes)
'37aa3296c523f6c5a7fd2102a9155dcc'(十六进制)(32 字节)
raw md5 ('This string will be hashed')
raw md5 ('这个字符串将被散列')
[55, 170, 50, 150, 197, 35, 246, 197, 167, 253, 33, 2, 169, 21, 93, 204] = (16 Bytes)
[55, 170, 50, 150, 197, 35, 246, 197, 167, 253, 33, 2, 169, 21, 93, 204] = (16 字节)
base64 of raw md5 string
原始 md5 字符串的 base64
N6oylsUj9sWn_SECqRVdzA==
N6oylsUj9sWn_SECqRVdzA==
My Final Hash
我的最终哈希
N6oylsUj9sWn_SECqRVdzAthis is actually the complete md5 in 22 ascii characters
N6oylsUj9sWn_SECqRVdzA这实际上是 22 个 ascii 字符的完整 md5
([you can strip the two trailing = there will always be two for md5-add them later when decoding. also replace + and / characters in b64 with any other i prefer -(dash) and _ (underscore) ]
([你可以去掉两个尾随 = 总是有两个用于 md5-稍后在解码时添加它们。也将 b64 中的 + 和 / 字符替换为我喜欢的任何其他字符 -(破折号)和 _(下划线)]