ユニコード文字のbase64エンコード/デコード

今のところAPIがあるのが、Firefoxのみかもだけど。

単純に、window.btoa("あいうえお")とすると、InvalidCharacterError: String contains an invalid characterと例外が発生する。

Encoding StandardのTextEncoder、TextDecoderが使えるなら、以下のように書ける。

function encodeToBase64 (str){
  return window.btoa(String.fromCharCode.apply(null, TextEncoder("utf-8").encode(str)));
}

function decodeFromBase64 (data) {
  return TextDecoder("utf-8").decode(Uint8Array([c.charCodeAt(0) for (c of window.atob(data))]))
}

TextEncoder, TextDecoderが使えない場合、は以下

function encodeToBase64 (str) {
  var data = encodeURI(str).replace(/%([0-9A-F]{2})/g,
              function(a,n){ return String.fromCharCode(parseInt(n, 16)); });
  return window.btoa(data);
}

function decodeFromBase64 (data) {
  var utf8 = window.atob(data).split("");
  return decodeURI(utf8.map(function(c){ return "%" + c.charCodeAt(0).toString(16); }).join(""));
}

ふと思ったこと

JSONコードを生成する際に、Unicodeエスケープすることがよくあると思うけど、base64化するとデータ量が減るのではないかとちょっと思った。ASCII文字が多い場合は逆に増えるけどね。
また、エンコード/デコードにコストが掛かるので、使用するのは考えものだが。

文字列  : あいうえお
Unicode : \u3042\u3044\u3046\u3048\u304A
Base64  : 44GC44GE44GG44GI44GK