v2.0 with proper encoding

This commit is contained in:
AJ ONeal 2015-06-10 17:59:01 -06:00
parent bff3fb392d
commit 10967b0a55
4 changed files with 192 additions and 3 deletions

View File

@ -3,8 +3,7 @@ utf8-typed
Base64, TypedArrays, and UTF-8 / Unicode conversions in Browser (and Node) JavaScript
This is based wholly on the work by good folks at the MDN.
See <https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding>
See <https://coolaj86.com/articles/base64-unicode-utf-8-javascript-and-you/>
API
===
@ -19,6 +18,24 @@ var base64 = Unibabel.arrToBase64(uint8Array)
var uint8Array = Unibabel.base64ToArr(base64)
```
**Normal APIs**
* utf8ToBuffer(utf8str) => array
* bufferToUtf8(array) => string
* utf8ToBase64(utf8str) => base64
* base64ToUtf8(base64) => string
* bufferToBase64(array) => base64
* base64ToBuffer(base64) => array
**Helper APIs**
* utf8ToBinaryString(utf8str) => binstr
* binaryStringToUtf8(binstr) => utf8str
* bufferToBinaryString(buffer) => binstr
* binaryStringToBuffer(binstr) => array
Examples
========
@ -51,3 +68,26 @@ Mozilla has licensed this code in the Public Domain, which means that I am at li
under the Apache 2, which is something that, general speaking, your legal department will feel more comfortable with.
See <https://developer.mozilla.org/en-US/docs/MDN/About#Copyrights_and_licenses>
ChangeLog
====
v2.0.0
------
The new implementation is binary compatible with node.js, TextEncoder,
and other more-common UTF-8 encodings.
It is also based on DOM APIs which result in much less code and are still
backwards compatible all the way back to IE6 (not on purpose, just that
it happens to work).
See <https://coolaj86.com/articles/base64-unicode-utf-8-javascript-and-you/>
v1.0.0
------
This version was based on the work by good folks at the MDN, however,
the UTF-8 conversion was not byte-compatible with other UTF-8 conversions
(such as node.js and TextEncoder), so don't use it.
See <https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding>

View File

@ -1,7 +1,7 @@
{
"name": "unibabel",
"main": "index.js",
"version": "1.0.0",
"version": "2.0.0",
"homepage": "https://github.com/coolaj86/unibabel-js",
"authors": [
"AJ ONeal <awesome@coolaj86.com>"

148
index.js Normal file
View File

@ -0,0 +1,148 @@
(function () {
'use strict';
function utf8ToBinaryString(str) {
var escstr = encodeURIComponent(str);
// replaces any uri escape sequence, such as %0A,
// with binary escape, such as 0x0A
var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
});
return binstr;
}
function utf8ToBuffer(str) {
var binstr = utf8ToBinaryString(str);
var buf = binaryStringToBuffer(binstr);
return buf;
}
function utf8ToBase64(str) {
var binstr = utf8ToBinaryString(str);
return btoa(binstr);
}
function binaryStringToUtf8(binstr) {
var escstr = binstr.replace(/(.)/g, function (m, p) {
var code = p.charCodeAt(p).toString(16).toUpperCase();
if (code.length < 2) {
code = '0' + code;
}
return '%' + code;
});
return decodeURIComponent(escstr);
}
function bufferToUtf8(buf) {
var binstr = Array.prototype.map.call(buf, function (ch) {
return '0x' + String.fromCharCode(ch);
}).join('');
return binaryStringToUtf8(binstr);
}
function base64ToUtf8(b64) {
var binstr = atob(b64);
return binaryStringToUtf8(binstr);
}
function bufferToBinaryString(buf) {
var binstr = Array.prototype.map.call(buf, function (ch) {
return '0x' + String.fromCharCode(ch);
}).join('');
return binstr;
}
function bufferToBase64(arr) {
var binstr = bufferToBinaryString(arr);
return btoa(binstr);
}
function binaryStringToBuffer(binstr) {
var buf;
if ('undefined' === typeof Uint8Array) {
buf = new Uint8Array(binstr.length);
} else {
buf = [];
}
Array.prototype.forEach.call(binstr, function (ch, i) {
buf[i] = ch.charCodeAt(0);
});
return buf;
}
function base64ToBuffer(base64) {
var binstr = atob(base64);
var buf = binaryStringToBuffer(binstr);
return buf;
}
// Hex Convenience Functions
, hexToBuffer: hexToBuffer
, bufferToHex: bufferToHex
function bufferToHex(arr) {
var i;
var len;
var hex = '';
var c;
for (i = 0, len = arr.length; i < len; i += 1) {
c = arr[i].toString(16);
if (c.length < 2) {
c = '0' + c;
}
hex += c;
}
return hex;
}
function hexToBuffer(hex) {
// TODO use Uint8Array or ArrayBuffer or DataView
var i;
var byteLen = hex.length / 2;
var arr;
var j = 0;
if (byteLen !== parseInt(byteLen, 10)) {
throw new Error("Invalid hex length '" + hex.length + "'");
}
arr = new Uint8Array(byteLen);
for (i = 0; i < byteLen; i += 1) {
arr[i] = parseInt(hex[j] + hex[j + 1], 16);
j += 2;
}
return arr;
}
window.Unibabel = {
utf8ToBinaryString: utf8ToBinaryString
, utf8ToBuffer: utf8ToBuffer
, utf8ToBase64: utf8ToBase64
, binaryStringToUtf8: binaryStringToUtf8
, bufferToUtf8: bufferToUtf8
, base64ToUtf8: base64ToUtf8
, bufferToBinaryString: bufferToBinaryString
, bufferToBase64: bufferToBase64
, binaryStringToBuffer: binaryStringToBuffer
, base64ToBuffer: base64ToBuffer
// compat
, strToUtf8Arr: utf8ToBuffer
, utf8ArrToStr: bufferToUtf8
, arrToBase64: bufferToBase64
, base64ToArr: base64ToBuffer
};
}());

1
unibabel-dom.js Symbolic link
View File

@ -0,0 +1 @@
index.js