C#MD5哈希函数返回奇怪的结果?

时间:2019-03-01 10:23:21

标签: c# utf-8 md5

我只是试图用C#创建一个MD5哈希程序。我的朋友给了我一个有关此的示例代码,但是当我尝试使用“ 123456”运行测试时,而不是返回正确的哈希结果

  

e10adc3949ba59abbe56e057f20f883e

它返回结果

  

ce0bfd15059b68d67688884d7a3d3e8c

我试图阅读主要代码,但仍然什么也没得到!

string value = textBox1.Text;

byte[] valueBytes = new byte[value.Length * 2];

Encoder encoder = Encoding.Unicode.GetEncoder();
encoder.GetBytes(value.ToCharArray(), 0, value.Length, valueBytes, 0, true);

MD5 md5 = new MD5CryptoServiceProvider();
byte[] hashBytes = md5.ComputeHash(valueBytes);

StringBuilder stringBuilder = new StringBuilder();

for (int i = 0; i < hashBytes.Length; i++)
{
    stringBuilder.Append(hashBytes[i].ToString("x2"));
}
textBox2.Text = stringBuilder.ToString();

2 个答案:

答案 0 :(得分:0)

您期望使用UTF8字符串,那么为什么要使用Unicode编码?使用UTF8,您将获得预期的结果:

string value = "123456";

byte[] valueBytes = new byte[value.Length]; // <-- don't multiply by 2!

Encoder encoder = Encoding.UTF8.GetEncoder(); // <-- UTF8 here
encoder.GetBytes(value.ToCharArray(), 0, value.Length, valueBytes, 0, true);

MD5 md5 = new MD5CryptoServiceProvider();
byte[] hashBytes = md5.ComputeHash(valueBytes);

StringBuilder stringBuilder = new StringBuilder();

for (int i = 0; i < hashBytes.Length; i++)
{
    stringBuilder.Append(hashBytes[i].ToString("x2"));
}

Console.WriteLine(stringBuilder.ToString()); // "e10adc3949ba59abbe56e057f20f883e"

答案 1 :(得分:0)

好像您的朋友使用Encoding.Default而不是Encoding.Unicode

.NET中的字符串为UTF16。不过,散列处理的是 bytes ,而不是字符串。该字符串必须转换为字节。为此,必须使用特定的编码。

如果使用.NET本机编码,即UTF16,则原始字节缓冲区将为12个字节长,哈希的十六进制表示将为ce0bfd15059b68d67688884d7a3d3e8c

var valueBytes=Encoding.Unicode.GetBytes("123456");
Debug.Assert(valueBytes.Length==12);
var md5=System.Security.Cryptography.MD5.Create();
byte[] hashBytes = md5.ComputeHash(valueBytes);
var hexText=String.Join("",hashBytes.Select(c=>c.ToString("x2")));

如果使用7位 US-ASCII 编码,则数组将为6个字节长,十六进制表示将为e10adc3949ba59abbe56e057f20f883e

var valueBytes=Encoding.ASCII.GetBytes("123456");
Debug.Assert(valueBytes.Length==6);

var md5=System.Security.Cryptography.MD5.Create();
byte[] hashBytes = md5.ComputeHash(valueBytes);
var hexText=String.Join("",hashBytes.Select(c=>c.ToString("x2")));

大多数代码页的第127个字节与7位US-ASCII字符匹配,因此most encodings(包括UTF8)将返回e10adc3949ba59abbe56e057f20f883e。以下编码将返回相同的哈希字符串:Encoding.GetEncoding(1251)(西里尔字母),Encoding.GetEncoding(20000)(繁体中文)将产生相同的哈希值。

Encoding.Default值返回与计算机的系统区域设置相对应的编码。这是非Unicode应用程序(例如使用ANSI字符串类型编译的C ++应用程序)使用的编码。

尽管

Encoding.GetEncoding(20273)会返回不同的值-这是IBM EBCDIC,即使对于英文字母和数字也使用不同的字节。这将返回:73e00d17ee63efb9ae91d274baae2459