2

I'm trying to get a hash of a string with SHA256 in my C# code, in Unity. I did the following:

using UnityEngine;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class URLGenerator : MonoBehaviour {

    void Start () {

        Debug.Log("myString: " + myString);

        SHA256 mySHA256 = SHA256Managed.Create(); 
        myHashBytes = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(myString)); 
        string myHash = Encoding.ASCII.GetString(myHashBytes); 

        Debug.Log("myHash: " + myHash);
    }
}

Here's the result:

myString: 3272017110434AMbx78va23
myHash: ?)wP<??|-?)??V:?3?6"???????a??

Are the ?representing invalid characters? If yes, why are they appearing? Did I do forgot something?

  • 1
    Try `Encoding.GetEncoding( "1252" )`. ASCII has only 7-bit characters, so every character that is > 127 will not be displayed correctly – Psi Mar 27 '17 at 09:21
  • 2
    Hashing produces a byte array, no reason those byte values should correspond to an ASCII character. – Chris Pickford Mar 27 '17 at 09:22
  • @Psi ASCII characters are 8bit wide. They were 7bits wide before [here you can read about that](http://stackoverflow.com/a/14690651/3179310) – mrogal.ski Mar 27 '17 at 09:25
  • @m.rogalski I'm afraid you are [wrong](https://en.wikipedia.org/wiki/ASCII) – Psi Mar 27 '17 at 09:40
  • @Psi ASCII characters are 8 bit wide even if you still use only 7 bits. That's what I meant, and that's why you have something like "extended ASCII". – mrogal.ski Mar 27 '17 at 09:43
  • They are 8 bits wide, but the code table only is defined for the least 7 bits. So the rest is undefined and therefor displayed as `?` – Psi Mar 27 '17 at 09:46
  • An hash is a binary data... You shouldn't print it. You should transform to hex digits, or base64 it. – xanatos Mar 27 '17 at 09:49

1 Answers1

2

Instead of

myHashBytes = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(myString)); 
string myHash = Encoding.ASCII.GetString(myHashBytes); 

you should

static string GetHash(SHA256 hash, string input)
{

    // Convert the input string to a byte array and compute the hash.
    byte[] data = hash.ComputeHash(Encoding.UTF8.GetBytes(input));

    // Create a new Stringbuilder to collect the bytes
    // and create a string.
    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of the hashed data 
    // and format each one as a hexadecimal string.
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }

    // Return the hexadecimal string.
    return sBuilder.ToString();
}

to get the string representation of the hash.

See HashAlgorithm.ComputeHash.

zwcloud
  • 4,546
  • 3
  • 40
  • 69