56

I am trying to:

  1. Generate a byte array.
  2. Convert that byte array to base64
  3. Convert that base64 string back to a byte array.

I've tried out a few solutions, for example those in this question.

For some reason the initial and final byte arrays do not match. Here is the code used:

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
    {
         byte[] originalArray = new byte[32];
         rng.GetBytes(key);
         string temp_inBase64 = Convert.ToBase64String(originalArray);
         byte[] temp_backToBytes = Encoding.UTF8.GetBytes(temp_inBase64);
    }

My questions are:

  1. Why do "originalArray" and "temp_backToBytes" not match? (originalArray has length of 32, temp_backToBytes has a length of 44, but their values are also different)

  2. Is it possible to convert back and forth, and if so, how do I accomplish this?

1 Answer 1

71

The reason the encoded array is longer by about a quarter is that base-64 encoding uses only six bits out of every byte; that is its reason of existence - to encode arbitrary data, possibly with zeros and other non-printable characters, in a way suitable for exchange through ASCII-only channels, such as e-mail.

The way you get your original array back is by using Convert.FromBase64String:

 byte[] temp_backToBytes = Convert.FromBase64String(temp_inBase64);
3
  • That worked, although if base64 uses only 6 out of every 8 bits, I would think the encoding would be shorter?
    – crawfish
    Commented Jul 24, 2012 at 15:47
  • 7
    @crawfish The encoding uses six out of eight bits in the output, leaving the two most significant ones set to zero. As the result, every group of three bytes (3*8=24 bits) becomes a group of four bytes (4*6=24 bits). If the number of bytes in the original is not divisible by three, special markers are added to the end. In your case, the next number divisible by 3 greater than 32 is 33, or 11*3. This means that the result is 11*4, or 44 bytes long. Commented Jul 24, 2012 at 15:57
  • The group three bytes (3*8=24 bits) becomes 32 bits. ie 1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 => b b 1 2 3 4 5 6 | b b 7 8 1 2 3 4 | b b 5 6 7 8 1 2 | b b 3 4 5 6 7 8 assuming MSB (left most bit, or big-endian) padding (b's would be on right end for LSB little-endian).
    – samus
    Commented Sep 20, 2017 at 20:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.