我尝试使用SHA256,我使用下面的代码以哈希的字符串:
using System;
using System.Security.Cryptography;
using System.Text;
public class Hash
{
public static string getHashSha256(string text)
{
byte[] bytes = Encoding.Unicode.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash)
{
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
}
然而,这个代码给出了比我朋友的PHP显著不同的结果,以及在线发生器(如该发电机 )
有谁知道错误是什么? 不同的基地?
Encoding.Unicode
是微软为UTF-16误导性名称(双宽编码,在Windows世界中使用的历史原因,但不使用其他任何人)。 http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx
如果您检查您的bytes
数组,你会看到每一个第二个字节是0x00
(因为双宽编码)。
您应该使用Encoding.UTF8.GetBytes
代替。
但同时,你会看到不同的结果,这取决于你是否不考虑终止'\0'
字节是你散列数据的一部分。 散列两个字节"Hi"
将给从散列三个字节一个不同的结果"Hi"
。 你必须决定你想做的事情。 (想必你想做哪一个朋友的PHP代码做什么。)
对于ASCII文本, Encoding.UTF8
肯定是合适的。 如果你的目标与你的朋友的代码完美兼容,甚至在非ASCII输入,你最好多试几个测试用例非ASCII字符,如é
和家
,看看你的结果是否仍然匹配。 如果没有,你必须搞清楚你的朋友真的是用什么编码; 它可能是使用Unicode的发明之前是受欢迎的8位“代码页”中的一个。 (同样,我认为Windows是最主要的原因,还有人需要担心“代码页”。)
我也有这个问题,实现另一种风格,但我忘了,我得到了它,因为它是2年前。
static string sha256(string randomString)
{
var crypt = new SHA256Managed();
string hash = String.Empty;
byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash += theByte.ToString("x2");
}
return hash;
}
当我输入类似abcdefghi2013
由于某种原因,它给我的登录模块不同的结果,并导致错误。 然后我试图修改代码以同样的方式通过Quuxplusone的建议,改变了编码从ASCII
到UTF8
那么它终于成功了!
static string sha256(string randomString)
{
var crypt = new System.Security.Cryptography.SHA256Managed();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
}
return hash.ToString();
}
再次感谢Quuxplusone的精彩和详细的解答! :)
在PHP版本,你可以在最后一个参数发送“真”,但默认为“假”。 ,把“SHA256”作为第一个参数时,下面的算法等同于默认的PHP的散列函数:
public static string GetSha256FromString(string strData)
{
var message = Encoding.ASCII.GetBytes(strData);
SHA256Managed hashString = new SHA256Managed();
string hex = "";
var hashValue = hashString.ComputeHash(message);
foreach (byte x in hashValue)
{
hex += String.Format("{0:x2}", x);
}
return hex;
}