Search code examples
c#converters

How to convert byte array to string and back?


I'm converting byte[] to string and back. The byte[] converted back is not identical to the original.

How do I convert bytes to string and back correctly?

A console application to illustrate this: Program.cs

_ = new TestByteConversion();

TestByteConversion.cs

internal class TestByteConversion
{
    public TestByteConversion()
    {
        var aes = Aes.Create();
        aes.GenerateKey();
        var keyAsString = GetKeyAsString(aes.Key);

        // I save it in a key value pair as string.
        // I get the value as string from dictionary.
        var keyAsyBytes = GetKeyFromString(keyAsString);

        // USE NuGet ConsoleTables !
        var table = new ConsoleTable("ID", "origin", "char", "new value");

        for (var i = 0; i < keyAsString.Length; i++)
        {
            table.AddRow(i, aes.Key[i], keyAsString[i], keyAsyBytes[i]);
        }

        table.Write();
    }

    public static byte[] GetKeyFromString(string keyAsString)
    {
        return Encoding.ASCII.GetBytes(keyAsString);
    }

    public static string GetKeyAsString(byte[] byteArray)
    {
        return Encoding.ASCII.GetString(byteArray);
    }
}

Solution

  • From the ASCIIEncoding.GetString docs:

    ASCIIEncoding does not provide error detection. Any byte greater than hexadecimal 0x7F is decoded as the Unicode question mark ("?").

    And 0x7F is 127, while byte is up to 255, so if the key has any element greater than 0x7F you will end up with non-reversible transformation.

    You can use Convert.ToBase64String/Convert.FromBase64String methods instead (or Convert.ToHexString/Convert.FromHexString). For example:

    var array = Enumerable.Range(0, 256)
        .Select(i => (byte)i)
        .ToArray();
    var s = Convert.ToHexString(array);
    var bytes = Convert.FromHexString(s);
    var sequenceEqual = bytes.SequenceEqual(array);
    Console.WriteLine(sequenceEqual); prints "True"