Base64 デコード
by
pacochi
2017-04-14 [2017/04/14 16:27:47]
選択部分を Base64 のエンコード済み文字列とみなしてデコードします。時々化けます。
@@ -5,30 +5,99 @@
* @javascript_url
*/
-((r = window.getSelection(), s = String(r), p = r.anchorNode, d, c) => {
+((r = window.getSelection(), s = String(r), p = r.anchorNode, e = '', a, t) => {
if (p.nodeType == 3) p = p.parentNode;
- s = s.replace(/^[^a-zA-Z0-9=\+\/]+/, '').split(/[^a-zA-Z0-9=\+\/\s\r\n]/)[0].replace(/[\s\r\n]/g, '');
+ s = atob(s.replace(/^[^a-zA-Z0-9=\+\/]+/, '').split(/[^a-zA-Z0-9=\+\/\s\r\n]/)[0].replace(/[\s\r\n]/g, ''));
if (!p || !s) return;
- s = escape(window.atob(s));
- d = () => {
-
- // TextDecoder 使おうとしたけど文字コード自動判別の仕方分かんなかった
- s = ECL[`Unescape${ECL.GetEscapeCodeType(s)}`](s);
- p.appendChild(Object.assign(document.createElement('span'), {
- textContent: s,
- style: 'display: block; margin: 1em; white-space: pre-wrap;'
- }));
-
- };
-
- if (window.ECL) return d();
-
- c = p.appendChild(document.createElement('script'));
- c.addEventListener('load', d);
- // http://www.junoe.jp/downloads/itoh/enc_js.shtml
- // https://gist.github.com/pacochi/84db66f331610768a50f
- c.src = 'https://cdn.rawgit.com/pacochi/84db66f331610768a50f/raw/167d9640b48aed4479a1396856fda5e1fe803a27/ecl_p.js';
-
-})();
+ a = Uint8Array.from(s, c => (c = c.charCodeAt(0), e += c.toString(16).padStart(3, '%0'), c));
+/*
+ecl.js から 文字コード判別部分だけ拝借
+http://www.junoe.jp/downloads/itoh/enc_js.shtml
+以下元コードのコピーライト表記、ライセンス不明
+//
+// Escape Codec Library: ecl.js (Ver.041208)
+//
+// Copyright (C) http://nurucom-archives.hp.infoseek.co.jp/digital/
+//
+*/
+ t = ((i = 0, T = '', c, C) => {
+
+ for (let [r, t] of new Map([
+ [/%([0-9A-DF][0-9A-F]%[8A]0%|E0%80|[0-7][0-9A-F]|C[01])%[8A]0|%00|%[7F]F/i, 'utf-16'],
+ [/%E[0-9A-F]%[8A]0%[8A]0|%[CD][0-9A-F]%[8A]0/i, 'utf-8'],
+ [/%F[DE]/i, /%8[0-9A-D]|%9[0-9A-F]|%A0/i.test(e) ? 'utf-16' : 'euc-jp'],
+ [/%1B/i, 'iso-2022-jp']
+ ])) if (r.test(e)) return t;
+
+ while (0 <= (c = a[i++]) && i < 2048) {
+
+ if (128 > c) continue;
+
+ // 4バイト文字の判定するためにちょっと改変
+ // 参考 : http://www.buildinsider.net/language/csharpunicode/01
+ if((C = a[i]) < 128) i++;
+ else if(194 <= c && c < 248 && C < 192) {
+
+ if (c < 224 && (T = 'utf-8', i++)) continue;
+ if (2 == a[i + 1] >> 6 && (T = 'utf-8', i += (2 == a[i + 2] >> 6 ? 3 : 2))) continue;
+
+ }
+
+ if (142 == c && 161 <= C && C < 224 && ('euc-jp' == T || (!T && (T = 'euc-jp')))) continue;
+ if (c < 161) return 'sjis';
+ T = (c < 224 && !T) ? (
+ ((164 == c && C < 244 || 165 == c && C < 247) && 161 <= C && i++) ? T : (
+ 224 <= C ? 'euc-jp' : 'sjis'
+ )
+ ) : 'euc-jp';
+
+ }
+
+ return(T || 'euc-jp');
+
+ })();
+
+ s = new TextDecoder(t).decode(a);
+ p.appendChild(Object.assign(document.createElement('span'), {
+ textContent: s,
+ style: 'display: block; margin: 1em; white-space: pre-wrap;'
+ }));
+
+})();
+
+/*
+経緯とか :
+http://q.hatena.ne.jp/1289780783
+http://d.hatena.ne.jp/kuro-yo/20101115/1289825621
+http://yurume.hatenadiary.jp/entry/20101116/QmFzZTY0
+今のとここの辺が見られたらいいやって思ってるから utf-16(UTF-16LE) 全然判別できない問題はおあずけ。
+
+初版は ecl.js の他、base64.js を使用、リンク切れてたけど以下と同じもの。
+https://github.com/dankogai/js-base64/blob/15166cc9bfe020d044e67148735e72158be01ab8/base64.js
+
+テスト用文字列
+
+iso-2022-jp
+GyRCJWElbSU5JE83Y0VcJDckPyEjGyhC
+GyhJUltdGyRCJE83YyQmJF4kQCRDJD8hIxsoQg==
+
+sjis
+g4GDjYNYgs2Mg5N7grWCvYFC
+0tvdgs2Mg4KkgtyCvoLBgr2BQg==
+
+euc-jp
+peGl7aW5pM+348XcpLekv6Gj
+jtKO247dpM+346SmpN6kwKTDpL+how==
+
+utf-8
+44Oh44Ot44K544Gv5r+A5oCS44GX44Gf44CC
+776S776b776d44Gv5r+A44GG44G+44Gg44Gj44Gf44CC
+8J+NiPCfmIvwn5KX
+
+utf-16
+4TDtMLkwbzDAbxJgVzBfMAIw
+kv+b/53/bzDAb0YwfjBgMGMwXzACMA==
+PNhI3z3YC9492Jfc
+*/
/*
* @title Base64 デコード
* @description 選択部分を Base64 のエンコード済み文字列とみなしてデコードします。時々化けます。
* @include *
* @javascript_url
*/
((r = window.getSelection(), s = String(r), p = r.anchorNode, e = '', a, t) => {
if (p.nodeType == 3) p = p.parentNode;
s = atob(s.replace(/^[^a-zA-Z0-9=\+\/]+/, '').split(/[^a-zA-Z0-9=\+\/\s\r\n]/)[0].replace(/[\s\r\n]/g, ''));
if (!p || !s) return;
a = Uint8Array.from(s, c => (c = c.charCodeAt(0), e += c.toString(16).padStart(3, '%0'), c));
/*
ecl.js から 文字コード判別部分だけ拝借
http://www.junoe.jp/downloads/itoh/enc_js.shtml
以下元コードのコピーライト表記、ライセンス不明
//
// Escape Codec Library: ecl.js (Ver.041208)
//
// Copyright (C) http://nurucom-archives.hp.infoseek.co.jp/digital/
//
*/
t = ((i = 0, T = '', c, C) => {
for (let [r, t] of new Map([
[/%([0-9A-DF][0-9A-F]%[8A]0%|E0%80|[0-7][0-9A-F]|C[01])%[8A]0|%00|%[7F]F/i, 'utf-16'],
[/%E[0-9A-F]%[8A]0%[8A]0|%[CD][0-9A-F]%[8A]0/i, 'utf-8'],
[/%F[DE]/i, /%8[0-9A-D]|%9[0-9A-F]|%A0/i.test(e) ? 'utf-16' : 'euc-jp'],
[/%1B/i, 'iso-2022-jp']
])) if (r.test(e)) return t;
while (0 <= (c = a[i++]) && i < 2048) {
if (128 > c) continue;
// 4バイト文字の判定するためにちょっと改変
// 参考 : http://www.buildinsider.net/language/csharpunicode/01
if((C = a[i]) < 128) i++;
else if(194 <= c && c < 248 && C < 192) {
if (c < 224 && (T = 'utf-8', i++)) continue;
if (2 == a[i + 1] >> 6 && (T = 'utf-8', i += (2 == a[i + 2] >> 6 ? 3 : 2))) continue;
}
if (142 == c && 161 <= C && C < 224 && ('euc-jp' == T || (!T && (T = 'euc-jp')))) continue;
if (c < 161) return 'sjis';
T = (c < 224 && !T) ? (
((164 == c && C < 244 || 165 == c && C < 247) && 161 <= C && i++) ? T : (
224 <= C ? 'euc-jp' : 'sjis'
)
) : 'euc-jp';
}
return(T || 'euc-jp');
})();
s = new TextDecoder(t).decode(a);
p.appendChild(Object.assign(document.createElement('span'), {
textContent: s,
style: 'display: block; margin: 1em; white-space: pre-wrap;'
}));
})();
/*
経緯とか :
http://q.hatena.ne.jp/1289780783
http://d.hatena.ne.jp/kuro-yo/20101115/1289825621
http://yurume.hatenadiary.jp/entry/20101116/QmFzZTY0
今のとここの辺が見られたらいいやって思ってるから utf-16(UTF-16LE) 全然判別できない問題はおあずけ。
初版は ecl.js の他、base64.js を使用、リンク切れてたけど以下と同じもの。
https://github.com/dankogai/js-base64/blob/15166cc9bfe020d044e67148735e72158be01ab8/base64.js
テスト用文字列
iso-2022-jp
GyRCJWElbSU5JE83Y0VcJDckPyEjGyhC
GyhJUltdGyRCJE83YyQmJF4kQCRDJD8hIxsoQg==
sjis
g4GDjYNYgs2Mg5N7grWCvYFC
0tvdgs2Mg4KkgtyCvoLBgr2BQg==
euc-jp
peGl7aW5pM+348XcpLekv6Gj
jtKO247dpM+346SmpN6kwKTDpL+how==
utf-8
44Oh44Ot44K544Gv5r+A5oCS44GX44Gf44CC
776S776b776d44Gv5r+A44GG44G+44Gg44Gj44Gf44CC
8J+NiPCfmIvwn5KX
utf-16
4TDtMLkwbzDAbxJgVzBfMAIw
kv+b/53/bzDAb0YwfjBgMGMwXzACMA==
PNhI3z3YC9492Jfc
*/
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。