91

I have a byte[] and I'm looking for the most efficient way to base64 encode it.

The problem is that the built in .Net method Convert.FromBase64CharArray requires a char[] as an input, and converting my byte[] to a char[] just to convert it again to a base64 encoded array seems pretty stupid.

Is there any more direct way to do it?

[[EDIT:]] I'll expaling what I want to achieve better - I have a byte[] and I need to return a new base64 encoded byte[]

5
  • what encoding is your byte array? ascii, utf8, etc? Commented Aug 29, 2012 at 12:57
  • You write that you want to convert TO base64 not "FromBase64" Commented Aug 29, 2012 at 12:59
  • 3
    Maybe I'm missing something.. but can't you use string Convert.ToBase64String(byte[]) and byte[] Convert.FromBase64String(string)? Commented Aug 29, 2012 at 13:00
  • @SimonWhitehead I've updated my question to clarify why this is not good enough Commented Aug 29, 2012 at 13:02
  • Converting a string into bytes is another story. Use byte[] Encoding.ASCII.GetBytes(theBase64String) Commented Aug 29, 2012 at 13:05

8 Answers 8

272

Byte[] -> String: use system.convert.tobase64string

Convert.ToBase64String(byte[] data) 

String -> Byte[]: use system.convert.frombase64string

Convert.FromBase64String(string data) 
Sign up to request clarification or add additional context in comments.

9 Comments

can you explain a usecase where you need a base64 byte[] as byte[] ? i never in my live had this need.
Converting a string into bytes is another story. Use Encoding.ASCII.GetBytes(theString)
@robnick: that's a huge no-go. every binary data that is getting base64'd is approx. 33% larger in size. so that's not really a useful usecase. nevertheless your usecase is just covered with byte[] -> string.
@StephanSchinkel Just try to implement downloading pdf or similar formatted files via ajax requests and you will have this problem. :) E.g. you don't have the option to open a new tab or window the current window has to be uninterrupted and in focus all the way. I don't think that 33% of any similarly formatted file counts as a very bad trade-off with the bandwidths of our time. I'm not saying its the proper way. But sometimes the business requirements demand it, thus its valid.
If you need to download a pdf or "formatted file" with ajax then just download it as a binary responsetype. No reason to convert it to text.
|
24

Base64 is a way to represent bytes in a textual form (as a string). So there is no such thing as a Base64 encoded byte[]. You'd have a base64 encoded string, which you could decode back to a byte[].

However, if you want to end up with a byte array, you could take the base64 encoded string and convert it to a byte array, like:

string base64String = Convert.ToBase64String(bytes); byte[] stringBytes = Encoding.ASCII.GetBytes(base64String); 

This, however, makes no sense because the best way to represent a byte[] as a byte[], is the byte[] itself :)

6 Comments

What if you would need to send the Base64 encoded form over the network? or to a file? then you will need it translated to byte[]. don't be too quick to say something makes no sense.
@AmitBens sure, but if the API takes a byte[] then you can typically send the original bytes. Maybe you're thinking of a case where you embed the byte[] within a textual structure (e.g. JSON) and then send the larger structure over a binary protocol (e.g. TCP)? You'd hardly ever have to directly convert a byte array to base64 only to convert it back to a byte[] again.
@erenEsonmez - MIME for email sending, uses base64 for attachments or messages not in ascii encoding, etc. you can hardly send an email without sending a base64 representation over the wire.
@ErenErsönmez Also note that some APIs require data be provided as a Base64 string (e.g. shopify). I agree its a silly but that's why people might need this.
@GeorgiG unlike your use case, OP wasn't interested in roundtrip of original bytes. See the discussions around FromBase64String in the question comments.
|
6

Here is the code to base64 encode directly to byte array (tested to be performing +-10% of .Net Implementation, but allocates half the memory):

 static public void testBase64EncodeToBuffer() { for (int i = 1; i < 200; ++i) { // prep test data byte[] testData = new byte[i]; for (int j = 0; j < i; ++j) testData[j] = (byte)(j ^ i); // test testBase64(testData); } } static void testBase64(byte[] data) { if (!appendBase64(data, 0, data.Length, false).SequenceEqual(System.Text.Encoding.ASCII.GetBytes(Convert.ToBase64String(data)))) throw new Exception("Base 64 encoding failed"); } static public byte[] appendBase64(byte[] data , int offset , int size , bool addLineBreaks = false) { byte[] buffer; int bufferPos = 0; int requiredSize = (4 * ((size + 2) / 3)); // size/76*2 for 2 line break characters if (addLineBreaks) requiredSize += requiredSize + (requiredSize / 38); buffer = new byte[requiredSize]; UInt32 octet_a; UInt32 octet_b; UInt32 octet_c; UInt32 triple; int lineCount = 0; int sizeMod = size - (size % 3); // adding all data triplets for (; offset < sizeMod;) { octet_a = data[offset++]; octet_b = data[offset++]; octet_c = data[offset++]; triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; buffer[bufferPos++] = base64EncodingTable[(triple >> 3 * 6) & 0x3F]; buffer[bufferPos++] = base64EncodingTable[(triple >> 2 * 6) & 0x3F]; buffer[bufferPos++] = base64EncodingTable[(triple >> 1 * 6) & 0x3F]; buffer[bufferPos++] = base64EncodingTable[(triple >> 0 * 6) & 0x3F]; if (addLineBreaks) { if (++lineCount == 19) { buffer[bufferPos++] = 13; buffer[bufferPos++] = 10; lineCount = 0; } } } // last bytes if (sizeMod < size) { octet_a = offset < size ? data[offset++] : (UInt32)0; octet_b = offset < size ? data[offset++] : (UInt32)0; octet_c = (UInt32)0; // last character is definitely padded triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; buffer[bufferPos++] = base64EncodingTable[(triple >> 3 * 6) & 0x3F]; buffer[bufferPos++] = base64EncodingTable[(triple >> 2 * 6) & 0x3F]; buffer[bufferPos++] = base64EncodingTable[(triple >> 1 * 6) & 0x3F]; buffer[bufferPos++] = base64EncodingTable[(triple >> 0 * 6) & 0x3F]; // add padding '=' sizeMod = size % 3; // last character is definitely padded buffer[bufferPos - 1] = (byte)'='; if (sizeMod == 1) buffer[bufferPos - 2] = (byte)'='; } return buffer; } 

3 Comments

kudos for doing it the hard way. But i will stick to System.Convert.
@FlorianFida Sure! the downside with System.Convert is when you need to get the Base64 into a bigger buffer you end up allocating extra buffers (and easily pollute the LOH/GC if you sizes are>80k), but as long as the code is not used very frequently its definitely safe to keep to your system methods :)
Amit Bens code has a good performance but till the moment you need to convert result to string or char[] (means UTF16). And this is quite often case. Then you will find it slower TWO times then System.Convert.ToBase64String. Just because of one System.Text.Encoding.ASCII.GetString(bytes) at the end. This was very unexpected for me.
5
byte[] base64EncodedStringBytes = Encoding.ASCII.GetBytes(Convert.ToBase64String(binaryData)) 

Comments

3

Based on your edit and comments.. would this be what you're after?

byte[] newByteArray = UTF8Encoding.UTF8.GetBytes(Convert.ToBase64String(currentByteArray)); 

1 Comment

We know that the base-64 string is going to be in the ASCII range, so it may be more efficient just to use the ASCII encoding directly (since it will be identical to what UTF8 would produce anyway)
0

You could use the String Convert.ToBase64String(byte[]) to encode the byte array into a base64 string, then Byte[] Convert.FromBase64String(string) to convert the resulting string back into a byte array.

Comments

0

To retrieve your image from byte to base64 string....

Model property:

 public byte[] NomineePhoto { get; set; } public string NomineePhoneInBase64Str { get { if (NomineePhoto == null) return ""; return $"data:image/png;base64,{Convert.ToBase64String(NomineePhoto)}"; } } 

IN view:

 <img style="height:50px;width:50px" src="@item.NomineePhoneInBase64Str" /> 

Comments

-1
 public void ProcessRequest(HttpContext context) { string constring = ConfigurationManager.ConnectionStrings["SQL_Connection_String"].ConnectionString; SqlConnection conn = new SqlConnection(constring); conn.Open(); SqlCommand cmd = new SqlCommand("select image1 from TestGo where TestId=1", conn); SqlDataReader dr = cmd.ExecuteReader(); dr.Read(); MemoryStream str = new MemoryStream(); context.Response.Clear(); Byte[] bytes = (Byte[])dr[0]; string d = System.Text.Encoding.Default.GetString(bytes); byte[] bytes2 = Convert.FromBase64String(d); //context.Response.Write(d); Image img = Image.FromStream(new MemoryStream(bytes2)); img.Save(context.Response.OutputStream, ImageFormat.Png); context.Response.Flush(); str.WriteTo(context.Response.OutputStream); str.Dispose(); str.Close(); conn.Close(); context.Response.End(); } 

1 Comment

I can see your answer getting down votes. Please explain your answer to avoid downvotes from the community in the future.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.