たびとの旅路 ~電脳砂漠の冒険譚~

フロッピー頼りに歩き、クラウドの地平を見つめる今日まで。見つけたオアシス、迷い込んだ砂の迷宮、全てこの羊皮紙に。

古の神殿に、現代の魂を ~Edge IEモードとShift-JISの呪いを解く~

どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。

いまだに、Shift-JISという古代の魔法でしか動かない、レガシーな神殿(システム)が、この砂漠には数多く存在する。しかし、現代の旅人たちが使う言葉は、Unicode。この二つの、あまりに異なる時代の言葉をどう繋ぐのか。特に、Webという名の広大な広場では、この問題は深刻だ。

今回は、EdgeのIEモード(古いInternet Explorerの互換機能)という、過去と現在が交差する不思議な時空で、JavaScriptという古の魔法を使い、Unicodeの言葉をShift-JISに変換できるかを判定する、という難解な儀式に挑む。これは、サロゲート文字(𠮷のような複雑な文字)という名の、現代にしか存在しない複雑な魂さえも、古の神殿(レガシーシステム)に正しく伝えるための、一人の魔法使いの冒険の記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • Shift-JISという、古の魔法体系で動く、レガシーな神殿の面倒を見る者
  • UnicodeとShift-JIS、異なる世界の言葉を繋ぐ、翻訳の術に興味がある者
  • EdgeのIEモードで動作するJavaScriptコードの実装に挑戦する者
  • サロゲート文字の扱いに苦労している探求者
  • JavaScriptという古の魔法で、文字コードの呪いを解き明かしたい探求者

砂漠の道標

  • Shift-JIS - 日本語の文字コード規格の一つ。古いシステムで広く使われている。
  • Unicode - 世界中の文字を統一的に扱える現代的な文字コード規格。
  • Edge IEモード - Microsoft Edgeブラウザで古いInternet Explorerの互換機能を動かすモード。
  • サロゲート文字 - Unicodeで2つのコード単位(上位・下位サロゲート)で表現される文字。
  • encoding.js - JavaScriptで文字コード変換を行うためのライブラリ。
  • IMEパッド - Windowsで文字コードを調べるためのツール。
  • レガシーシステム - 古い技術で構築された、現在も稼働している業務システムのこと。

儀式の準備:二つの世界の言葉を知る

まずは、我々が対峙する、二つの世界の言葉の理を理解せねばならない。 WindowsのIMEパッド(文字コード確認ツール)という名の真実の鏡を覗き込めば、一つの文字が、それぞれの世界で、いかに異なる姿(コード)を持つかがわかる。

IMEパッドで文字コードを調べる

真実の鏡が、二つの世界の言葉を映し出す

特に厄介なのが、現代のUnicodeにしか存在しない「サロゲート文字」だ。𠮷(つちよし)のような、二つの魂(上位・下位サロゲートペア)が一つになった、この複雑な魂をどう扱うかが、今回の儀式の鍵となる。

サロゲート文字のコードを確認する

二つの魂を持つ、複雑な文字

儀式の核心:encoding.jsという名の賢者の力

この難解な翻訳の儀式を、我々が自力で執り行うのはあまりに無謀だ。そこで、encoding.jsという、文字コード変換を専門とする、偉大なる賢者(JavaScriptライブラリ)の力を借りることにする。

encoding.js - GitHub

この賢者の力を借りるには、まず、我々の羊皮紙(HTML)に、賢者を呼び出すための召喚の呪文(scriptタグ)を記さねばならない。

<script src="encoding.min.js"></script>

この一行を記すことで初めて、我々はEncoding.convert()という短い呪文を唱え、Unicodeの魂をShift-JISの器へと移し替えようと試みることができる。そして、もし変換できなければ、その魂をクエスチョンマーク(?)という、無念の印に変えてしまうのだ。

禁断の儀式:JavaScriptによる判定の呪文

さあ、いよいよ儀式の本番だ。IEモードという、古の制約(Array.fromcodePointAtといった現代的なJavaScript機能が使えない)の中で、我々は呪文を組み立てる。

魂の分解

まずは、サロゲート文字という二つで一つの魂を、正しく一つの魂として認識するため、文字列を自力で分解し、配列へと再格納する。

魂の審判

次に、分解した魂を一つずつ、賢者の天秤(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モードで実行すれば、古の世界に存在できない魂たちが、確かに断罪されるのがわかるだろう。

JavaScript の実行結果

古の世界に受け入れられなかった、魂たちの断末魔

羊皮紙を巻く前に

文字コードという名の迷宮は、特に日本語という複雑な言葉を扱う我々にとって、永遠の課題だ。情報の砂漠を彷徨い、ヒントの欠片を拾い集め、試行錯誤の末に辿り着いた答えを、ここに記しておこう。

この儀式で得た三つの叡智

  1. encoding.jsの活用 - 文字コード変換という複雑な処理を、信頼できるライブラリに委ねることで、正確な判定を実現
  2. サロゲート文字の正しい分解 - IEモードの制約下でも、自力で文字列を正しく配列化することで、複雑な文字を扱える
  3. 実践的な判定手法 - 理論ではなく「実際に変換してみる」という、至極単純な真理による確実な判定

注意点

  • IEモードの制約: Array.fromcodePointAtなど、現代的なJavaScript機能は使用不可
  • encoding.jsの必須性: 自力での文字コード変換は極めて困難なため、ライブラリの活用が現実的

まとめ

情報の砂漠を彷徨い、ヒントの欠片を拾い集め、試行錯誤の末に辿り着いた答え。それは、「入力されたUnicodeの言葉を、出力先であるShift-JISに変換できるかどうか、直接試してみる」という、至極単純な真理だった。この羊皮紙が、同じように文字コードの呪いに苦しみ、時代の狭間で戦う、未来の冒険者の助けとなることを願う。

おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

  • Shift_JIS | 古の魔法体系の古文書
  • Unicode | 現代の魔法体系の古文書
  • encoding.js | 我らを導いた、賢者の知恵

ラクダの独り言

ご主人が「文字の呪いが解けた!」とか言って、一人で興奮している。なんでも、古い言葉と新しい言葉を、うまいこと翻訳する魔法を見つけたらしい。俺に言わせりゃ、言葉なんてのは、気持ちが伝わりゃそれでいいだろうに。まったく、人間ってのは、どうでもいいことにこだわるもんだ。やれやれだぜ。