Peter
Peter

Reputation: 803

"Specified value has invalid Control characters" when converting SHA512 output to string

I am attempting to create an Hash for an API. my input is something like this:

FBN|Web|3QTC0001|RS1|260214133217|000000131127897656

And my expected output is like :

17361DU87HT56F0O9967E34FDFFDFG7UO334665324308667FDGJKD66F9888766DFKKJJR466634HH6566734JHJH34766734NMBBN463499876554234343432456

I tried the bellow but I keep getting "Specified value has invalid Control characters. Parameter name: value"

I am actually doing this in a REST service.

public static string GetHash(string text)
{
    string hash = "";
    SHA512 alg = SHA512.Create();
    byte[] result = alg.ComputeHash(Encoding.UTF8.GetBytes(text));
    hash = Encoding.UTF8.GetString(result);        
    return hash;
}

What am I missing?

Upvotes: 6

Views: 15977

Answers (3)

Andrew Morton
Andrew Morton

Reputation: 25067

You might want to consider using Base64 encoding (AKA UUEncode):

public static string GetHash(string text)
{
    SHA512 alg = SHA512.Create();
    byte[] result = alg.ComputeHash(Encoding.UTF8.GetBytes(text));
    return Convert.ToBase64String(result);
}

For your example string, the result is

OJgzW5JdC1IMdVfC0dH98J8tIIlbUgkNtZLmOZsjg9H0wRmwd02tT0Bh/uTOw/Zs+sgaImQD3hh0MlzVbqWXZg==

It has an advantage of being more compact than encoding each byte into two characters: three bytes takes four characters with Base64 encoding or six characters the other way.

Upvotes: 2

user2864740
user2864740

Reputation: 61975

The problem is Encoding.UTF8.GetString(result) as the data in result is invalid UTF-8 (it's just binary goo!) so trying to convert it to text is invalid - in general, and specifically for this input - which results in the Exception being thrown.

Instead, convert the byte[] to the hex representation of said byte sequence; don't treat it as UTF-8 encoded text.

See the questions How do you convert Byte Array to Hexadecimal String, and vice versa? and How can I convert a hex string to a byte array?, which discuss several different methods of achieving this task.

Upvotes: 4

JaredPar
JaredPar

Reputation: 755457

In order to make this work you need to convert the individual byte elements into a hex representation

var builder = new StringBuilder();
foreach(var b in result) {
  builder.AppendFormat("{0:X2}", b);
}
return builder.ToString();

Upvotes: 2

Related Questions