53

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?

Community
  • 1
  • 1
crawfish
  • 853
  • 4
  • 11
  • 14

1 Answers1

68

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);
Jason Towne
  • 8,014
  • 5
  • 54
  • 69
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • That worked, although if base64 uses only 6 out of every 8 bits, I would think the encoding would be shorter? – crawfish Jul 24 '12 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. – Sergey Kalinichenko Jul 24 '12 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 Sep 20 '17 at 20:39