Permalink
First release, with test.
74 lines (66 sloc)
3.39 KB
| (function (root, factory) { | |
| if (typeof define === 'function' && define.amd) { | |
| // AMD. Register as an anonymous module. | |
| define([], function() {factory(root);}); | |
| } else factory(root); | |
| // node.js has always supported base64 conversions, while browsers that support | |
| // web workers support base64 too, but you may never know. | |
| })(typeof exports !== "undefined" ? exports : this, function(root) { | |
| if (root.atob) { | |
| // Some browsers' implementation of atob doesn't support whitespaces | |
| // in the encoded string (notably, IE). This wraps the native atob | |
| // in a function that strips the whitespaces. | |
| // The original function can be retrieved in atob.original | |
| try { | |
| root.atob(" "); | |
| } catch(e) { | |
| root.atob = (function(atob) { | |
| var func = function(string) { | |
| return atob(String(string).replace(/[\t\n\f\r ]+/g, "")); | |
| }; | |
| func.original = atob; | |
| return func; | |
| })(root.atob); | |
| } | |
| return; | |
| } | |
| // base64 character set, plus padding character (=) | |
| var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", | |
| // Regular expression to check formal correctness of base64 encoded strings | |
| b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; | |
| root.btoa = function(string) { | |
| string = String(string); | |
| var bitmap, a, b, c, | |
| result = "", i = 0, | |
| rest = string.length % 3; // To determine the final padding | |
| for (; i < string.length;) { | |
| if ((a = string.charCodeAt(i++)) > 255 | |
| || (b = string.charCodeAt(i++)) > 255 | |
| || (c = string.charCodeAt(i++)) > 255) | |
| throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."); | |
| bitmap = (a << 16) | (b << 8) | c; | |
| result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) | |
| + b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63); | |
| } | |
| // If there's need of padding, replace the last 'A's with equal signs | |
| return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result; | |
| }; | |
| root.atob = function(string) { | |
| // atob can work with strings with whitespaces, even inside the encoded part, | |
| // but only \t, \n, \f, \r and ' ', which can be stripped. | |
| string = String(string).replace(/[\t\n\f\r ]+/g, ""); | |
| if (!b64re.test(string)) | |
| throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); | |
| // Adding the padding if missing, for semplicity | |
| string += "==".slice(2 - (string.length & 3)); | |
| var bitmap, result = "", r1, r2, i = 0; | |
| for (; i < string.length;) { | |
| bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 | |
| | (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++))); | |
| result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) | |
| : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) | |
| : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); | |
| } | |
| return result; | |
| }; | |
| }); |