为什么这些代码块产生不同的结果?

时间:2018-04-04 17:08:21

标签: c# .net xamarin base64 sha512

以下是2个类似的代码块。他们接受一个字符串,在SHA512中加密,然后转换为Base64,我无法获得第二个代码块,以产生与使用在线计算器和编码器的手动测试相同的结果。所以我逐步打破了这个过程,发现它能够产生与我的手动测试相同的结果,但前提是它的行为与第一个代码块相同。为什么这两个代码块产生不同的结果?谢谢!

    private void EditText_AfterTextChanged(object sender, AfterTextChangedEventArgs e)
    {
        //This builds a string to encrypt.
        string domain = txtDomain.Text;
        string username = txtUsername.Text;
        string pin = txtPin.Text;
        txtPreview.Text = string.Format("{0}+{1}+{2}", domain, username, pin);

        //This takes the above string, encrypts it.
        StringBuilder Sb = new StringBuilder();
        SHA512Managed HashTool = new SHA512Managed();
        Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(txtPreview.Text));
        Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
        HashTool.Clear();

        //This rebuilds the calculated hash for manual comparison.
        foreach (Byte b in EncryptedBytes)
            Sb.Append(b.ToString("x2"));
        txtHash.Text = Sb.ToString();

        //This takes the rebuilt hash and re-converts it to bytes before encoding it in Base64
        EncryptedBytes = System.Text.Encoding.UTF8.GetBytes(string.Concat(txtHash.Text));
        txtResult.Text = Convert.ToBase64String(EncryptedBytes);

    }

    private void EditText_AfterTextChanged(object sender, AfterTextChangedEventArgs e)
    {
        //This builds a string to encrypt.
        string domain = txtDomain.Text;
        string username = txtUsername.Text;
        string pin = txtPin.Text;
        txtPreview.Text = string.Format("{0}+{1}+{2}", domain, username, pin);

        //This takes the above string, encrypts it.
        StringBuilder Sb = new StringBuilder();
        SHA512Managed HashTool = new SHA512Managed();
        Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(txtPreview.Text));
        Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
        HashTool.Clear();

        //This takes the EncryptedBytes and converts them to base64.
        txtResult.Text = Convert.ToBase64String(EncryptedBytes);

        //This reverses the EncryptedBytes into readable hash for manual comparison
        foreach (Byte b in EncryptedBytes)
        Sb.Append(b.ToString("x2"));
        txtHash.Text = Sb.ToString();
    }

1 个答案:

答案 0 :(得分:-1)

找到了答案,不,谢谢你的不太有用的downvotes ..

  

Encoding.Unicode是Microsoft对UTF-16的误导性名称(双宽编码,由于历史原因在Windows世界中使用但未被其他任何人使用)。 http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx

     

如果你检查你的字节数组,你会看到每隔一个字节是0x00(因为双宽编码)。

     

您应该使用Encoding.UTF8.GetBytes。

     

但是,根据您是否认为终止'\ 0'字节是您正在散列的数据的一部分,您将看到不同的结果。散列两个字节“Hi”将通过散列三个字节“Hi”给出不同的结果。你必须决定你想做什么。 (据推测,你想要做你朋友的PHP代码所做的任何事情。)

     

对于ASCII文本,Encoding.UTF8肯定是合适的。如果您的目标是与朋友的代码完美兼容,即使在非ASCII输入上,您最好尝试使用非ASCII字符(例如é和家)的几个测试用例,看看您的结果是否仍然匹配。如果没有,你将不得不弄清楚你的朋友正在使用什么编码;它可能是在Unicode发明之前流行的8位“代码页”之一。 (同样,我认为Windows是任何人仍然需要担心“代码页”的主要原因。)

来源:Hashing a string with Sha256