commit
5ac9f99e97
4 changed files with 150 additions and 0 deletions
@ -0,0 +1,14 @@ |
|||||
|
Intro |
||||
|
===== |
||||
|
|
||||
|
`base64-js` does basic base64 encoding/decoding in pure JS. Many browsers already have this functionality, but it is for text data, not all-purpose binary data. |
||||
|
|
||||
|
Sometimes encoding/decoding binary data in the browser is useful, and that is what this module does. |
||||
|
|
||||
|
API |
||||
|
=== |
||||
|
|
||||
|
`base64-js` has two exposed functions, `toByteArray` and `fromByteArray`, which both take a single argument. |
||||
|
|
||||
|
* toByteArray- Takes a base64 string and returns a byte array |
||||
|
* fromByteArray- Takes a byte array and returns a base64 string |
@ -0,0 +1,78 @@ |
|||||
|
(function (exports) { |
||||
|
'use strict'; |
||||
|
|
||||
|
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |
||||
|
|
||||
|
function b64ToByteArray(b64) { |
||||
|
var i, l, tmp, hasPadding, arr = []; |
||||
|
|
||||
|
if (i % 4 > 0) { |
||||
|
throw 'Invalid string. Length must be a multiple of 4'; |
||||
|
} |
||||
|
|
||||
|
hasPadding = /=$/.test(b64); |
||||
|
|
||||
|
l = hasPadding ? b64.length - 4: b64.length; |
||||
|
|
||||
|
for (i = 0; i < l; i += 4) { |
||||
|
tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); |
||||
|
arr.push((tmp & 0xFF0000) >> 16); |
||||
|
arr.push((tmp & 0xFF00) >> 8); |
||||
|
arr.push(tmp & 0xFF); |
||||
|
} |
||||
|
|
||||
|
if (hasPadding) { |
||||
|
b64 = b64.substring(i, b64.indexOf('=')); |
||||
|
|
||||
|
if (b64.length === 2) { |
||||
|
tmp = (lookup.indexOf(b64[0]) << 2) | (lookup.indexOf(b64[1]) >> 4); |
||||
|
arr.push(tmp & 0xFF); |
||||
|
} else { |
||||
|
tmp = (lookup.indexOf(b64[0]) << 10) | (lookup.indexOf(b64[1]) << 4) | (lookup.indexOf(b64[2]) >> 2); |
||||
|
arr.push((tmp >> 8) & 0xFF); |
||||
|
arr.push(tmp & 0xFF); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return arr; |
||||
|
} |
||||
|
|
||||
|
function uint8ToBase64(uint8) { |
||||
|
var i, |
||||
|
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
|
||||
|
output = "", |
||||
|
temp, length; |
||||
|
|
||||
|
function tripletToBase64 (num) { |
||||
|
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; |
||||
|
}; |
||||
|
|
||||
|
// go through the array every three bytes, we'll deal with trailing stuff later
|
||||
|
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { |
||||
|
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); |
||||
|
output += tripletToBase64(temp); |
||||
|
} |
||||
|
|
||||
|
// pad the end with zeros, but make sure to not forget the extra bytes
|
||||
|
switch (extraBytes) { |
||||
|
case 1: |
||||
|
temp = uint8[uint8.length - 1]; |
||||
|
output += lookup[temp >> 2]; |
||||
|
output += lookup[(temp << 4) & 0x3F]; |
||||
|
output += '=='; |
||||
|
break; |
||||
|
case 2: |
||||
|
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); |
||||
|
output += lookup[temp >> 10]; |
||||
|
output += lookup[(temp >> 4) & 0x3F]; |
||||
|
output += lookup[(temp << 2) & 0x3F]; |
||||
|
output += '='; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return output; |
||||
|
} |
||||
|
|
||||
|
module.exports.toByteArray = b64ToByteArray; |
||||
|
module.exports.fromByteArray = uint8ToBase64; |
||||
|
}()); |
@ -0,0 +1,19 @@ |
|||||
|
{ |
||||
|
"author": "T. Jameson Little <t.jameson.little@gmail.com>", |
||||
|
"name": "base64-js", |
||||
|
"description": "Base64 encoding/decoding in pure JS", |
||||
|
"version": "0.0.1", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git://github.com/beatgammit/deflate-js.git" |
||||
|
}, |
||||
|
"main": "lib/b64.js", |
||||
|
"scripts": { |
||||
|
"test": "cd test; node runner.js; cd -" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 0.4" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"devDependencies": {} |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
(function () { |
||||
|
'use strict'; |
||||
|
|
||||
|
var b64 = require('../lib/b64'), |
||||
|
checks = [ |
||||
|
'a', |
||||
|
'aa', |
||||
|
'aaa', |
||||
|
'hi', |
||||
|
'hi!', |
||||
|
'hi!!', |
||||
|
'sup', |
||||
|
'sup?', |
||||
|
'sup?!' |
||||
|
], |
||||
|
res; |
||||
|
|
||||
|
res = checks.some(function (check) { |
||||
|
var b64Str, |
||||
|
arr, |
||||
|
str; |
||||
|
|
||||
|
b64Str = b64.fromByteArray(Array.prototype.map.call(check, function (char) { return char.charCodeAt(0); })); |
||||
|
|
||||
|
arr = b64.toByteArray(b64Str); |
||||
|
str = arr.map(function (byte) { return String.fromCharCode(byte); }).join(''); |
||||
|
if (check !== str) { |
||||
|
console.log('Fail:', check); |
||||
|
console.log('Base64:', b64Str); |
||||
|
return true; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
if (res) { |
||||
|
console.log('Test failed'); |
||||
|
} else { |
||||
|
console.log('All tests passed!'); |
||||
|
} |
||||
|
}()); |
Loading…
Reference in new issue