どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。
いまだに、Shift-JISという古代の魔法でしか動かない、レガシーな神殿(システム)が、この砂漠には数多く存在する。しかし、現代の旅人たちが使う言葉は、Unicode。この二つの、あまりに異なる時代の言葉をどう繋ぐのか。特に、Webという名の広大な広場では、この問題は深刻だ。
今回は、EdgeのIEモードという、過去と現在が交差する不思議な時空で、JavaScriptという古の魔法を使い、Unicodeの言葉をShift-JISに変換できるかを判定する、という難解な儀式に挑む。これは、サロゲート文字という名の、現代にしか存在しない複雑な魂さえも、古の神殿に正しく伝えるための、一人の魔法使いの冒険の記録である。
この羊皮紙のあらまし
- この羊皮紙のあらまし
- この羊皮紙が導く者
- 儀式の準備:二つの世界の言葉を知る
- 儀式の核心:encoding.jsという名の賢者の力
- 禁断の儀式:JavaScriptによる判定の呪文
- 羊皮紙を巻く前に
- 砂漠で見つけた魔法のランプ
- ラクダの独り言
この羊皮紙が導く者
- Shift-JISという、古の魔法体系で動く、レガシーな神殿の面倒を見る者
- UnicodeとShift-JIS、異なる世界の言葉を繋ぐ、翻訳の術に興味がある者
- JavaScriptという古の魔法で、文字コードの呪いを解き明かしたい探求者
儀式の準備:二つの世界の言葉を知る
まずは、我々が対峙する、二つの世界の言葉の理を理解せねばならない。 WindowsのIMEパッドという名の真実の鏡を覗き込めば、一つの文字が、それぞれの世界で、いかに異なる姿(コード)を持つかがわかる。
特に厄介なのが、現代のUnicodeにしか存在しない「サロゲート文字」だ。𠮷(つちよし)のような、二つの魂(上位・下位サロゲート)が一つになった、この複雑な魂をどう扱うかが、今回の儀式の鍵となる。
儀式の核心:encoding.jsという名の賢者の力
この難解な翻訳の儀式を、我々が自力で執り行うのはあまりに無謀だ。そこで、encoding.jsという、文字コードの全てを知り尽くした、偉大なる賢者の力を借りることにする。
この賢者の力を借りるには、まず、我々の羊皮紙(HTML)に、賢者を呼び出すための召喚の呪文を記さねばならない。
<script src="encoding.min.js"></script>
この一行を記すことで初めて、我々はEncoding.convert()という短い呪文を唱え、Unicodeの魂をShift-JISの器へと移し替えようと試みることができる。そして、もし変換できなければ、その魂をクエスチョンマーク(?)という、無念の印に変えてしまうのだ。
禁断の儀式:JavaScriptによる判定の呪文
さあ、いよいよ儀式の本番だ。IEモードという、古の制約(Array.fromやcodePointAtが使えない)の中で、我々は呪文を組み立てる。
魂の分解
まずは、サロゲート文字という二つで一つの魂を、正しく一つの魂として認識するため、文字列を自力で分解し、配列へと再格納する。
魂の審判
次に、分解した魂を一つずつ、賢者の天秤(Encoding.convert)にかける。
クエスチョンマークに変換された魂があれば、それは古の世界には存在できない魂だ。その魂を、ngWordsという名の牢獄へと送り込む。
const SampleText = "a?1②㉑㊿𠮷💛"; // サロゲート文字を正しく一文字として認識するため、自力で配列化 var items = SampleText.split(''); var utf16 = []; // ... (サロゲートペアを結合する処理) ... // 魂を一つずつ、賢者の天秤にかける var sjis = []; var ngWords = []; for (var i = 0; i < utf16.length; i++) { var code = utf16[i].charCodeAt(0); // 賢者の力で、Shift-JISへの変換を試みる var buff = Encoding.convert([code], { to: 'SJIS', from: 'UNICODE' }); // 賢者が答えを返さなかった(サロゲート文字)、 // または、クエスチョンマークに変えられてしまった場合 if (buff.length == 0 || (buff[0] == 0x3f && code != 0x3f)) { // その魂を、牢獄へ送る ngWords.push(utf16[i]); } } // もし、牢獄に魂が一つでもあれば、警鐘を鳴らす if (0 < ngWords.length) { alert('Shift-JIS に変換できない文字が見つかりました。\n' + ngWords); }
この呪文をEdgeのIEモードで実行すれば、古の世界に存在できない魂たちが、確かに断罪されるのがわかるだろう。
羊皮紙を巻く前に
文字コードという名の迷宮は、特に日本語という複雑な言葉を扱う我々にとって、永遠の課題だ。 情報の砂漠を彷徨い、ヒントの欠片を拾い集め、試行錯誤の末に辿り着いた答え。それは、「入力されたUnicodeの言葉を、出力先であるShift-JISに変換できるかどうか、直接試してみる」という、至極単純な真理だった。
この羊皮紙が、同じように文字コードの呪いに苦しみ、時代の狭間で戦う、未来の冒険者の助けとなることを願う。
おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。
砂漠で見つけた魔法のランプ
- Shift_JIS | 古の魔法体系の古文書
- Unicode | 現代の魔法体系の古文書
- encoding.js | 我らを導いた、賢者の知恵
ラクダの独り言
ご主人が「文字の呪いが解けた!」とか言って、一人で興奮している。なんでも、古い言葉と新しい言葉を、うまいこと翻訳する魔法を見つけたらしい。俺に言わせりゃ、言葉なんてのは、気持ちが伝わりゃそれでいいだろうに。まったく、人間ってのは、どうでもいいことにこだわるもんだ。やれやれだぜ。