Base64 is an encoding scheme that allows binary data to be represented as text. This is useful when you need to transfer binary data over a medium that only supports text, such as email or HTTP requests. In this tutorial, we’ll cover how to encode and decode strings using Base64 in JavaScript.
Introduction to Base64
Base64 uses 64 characters to represent binary data: A-Z, a-z, 0-9, +, /, and =. The = character is used for padding when the length of the binary data is not a multiple of 3.
Encoding Strings with Base64
To encode a string using Base64 in JavaScript, you can use the btoa()
function. This function takes a string as input and returns the encoded Base64 string.
const originalString = "Hello World!";
const encodedString = btoa(originalString);
console.log(encodedString); // Output: SGVsbG8gV29ybGQh
Note that btoa()
only works with strings where each character represents an 8-bit byte. If you’re working with Unicode strings, you may need to encode them first using a function like _utf8_encode()
from the example code below.
Decoding Base64 Strings
To decode a Base64 string in JavaScript, you can use the atob()
function. This function takes an encoded Base64 string as input and returns the original string.
const encodedString = "SGVsbG8gV29ybGQh";
const decodedString = atob(encodedString);
console.log(decodedString); // Output: Hello World!
Implementing Base64 Encoding and Decoding
If you need more control over the encoding and decoding process, or if you’re working with older browsers that don’t support btoa()
and atob()
, you can implement your own Base64 encoding and decoding functions using JavaScript. Here’s an example implementation:
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = this._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
decode: function(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this._utf8_decode(output);
return output;
},
_utf8_encode: function(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
_utf8_decode: function(utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
};
Conclusion
In this tutorial, we’ve covered how to encode and decode strings using Base64 in JavaScript. We’ve also implemented our own Base64 encoding and decoding functions for more control over the process.
Example Use Cases
- Encoding images as Base64 strings for inclusion in HTML or CSS files
- Decoding Base64 strings received from a server or API
- Using Base64 to transfer binary data over text-based protocols like HTTP or email
Note that while Base64 encoding can be useful, it also increases the size of the data by about 33%. This should be taken into account when deciding whether to use Base64 encoding in your application.