• ストレンジなラブ

インターネットなどで公開されているテキストファイルの大半がUTF-8形式となり、いまではShift JISコードのテキストファイルは少数派になりつつある。しかし、つい最近まで、WindowsでUTF-8といえば、“Byte Order Mark”(BOM)付きが普通だった。BOM付きのUTF-8形式テキストは、ExcelなどMicrosoft製品では快調に読めるものの、エラーになるサードパーティ・アプリケーションや、Linuxなどで問題を起こすなど、使いやすいものではなかった。このため、Windows 7、8の頃は、テキストファイルとしては、まだ以前からのShift JISコードを使うユーザーも少なくなかった。当時、筆者も原稿のファイルは、Shift JISを使っていた。

メモ帳がBOMなしのUTF-8で保存できるようになったのは、2019年のWindows 10 Ver.1903からである。マイクロソフトがBOM付きのUTF-8にこだわったのは、Shift JISとの判別のためだ。

Shift JISは、8bitコードの0xA1~0xDFの範囲で定義されていた「半角片仮名」(図01)と、併用が可能なように0x81~0x9F、0xE0~0xFCまでを第一バイト、第二バイトの範囲を0x40~0xFC(一部抜けあり)とする2バイトコードとして定義されている(図02)。成立は1982年頃。

  • 図01: 漢字が利用できる以前に使われていたのは、俗に「8 bit JISコード」などと呼ばれるもので、ASCII文字と半角片仮名(JIS X 0201)を使うことができた

  • 図02: Shift JISは、8 bit JISコードの未割り当て部分に漢字コードの1バイト目を割り当て、ASCII、半角片仮名と漢字を共存できるようにした

こうしたエンコード形式になった理由は、いろいろと言われているが、基本的にはMicrosoftなどの「都合」である。エスケープシーケンスを使って文字コードを切り替えることは、MS-DOSやBASICインタプリタなどの文字処理ルーチンの大幅な改良が必要で、かつ当時の非力なCPUには負荷が高かった。また、過去にBASICマシンで作られたプログラムを動作させるには半角片仮名の利用は必須だった。そこで、漢字は表示幅が2倍の全角で2バイト、半角の文字は1バイトとして、MS-DOSやBASICインタプリタなどは最低限の改修で対応できるようなエンコード方法としてShift JIS方式が選択された。MicrosoftのMS-DOSや各種言語インタプリタやコンパイラ、あるいはサードパーティ・アプリケーションなども当時ほとんどがアセンブラで書かれており大きな修正は困難だった。見方によってはShift JISは内部エンコード方式なので、何を使うも自由と言えば自由。しかし、日本語の標準的なエンコード形式として普及し、さらに各社で収録文字などが異なるといった問題が発生、MicrosoftとしてもWindows 3.1で標準として定義を行うことになる

これに対して、Shift JISからおよそ10年後、1993年に発表されたUTF-8は、第一バイトを0xC2~0xF4までとする2、3、4バイトの可変長のコードを使う。ただし、2バイト目以降は、0x80~0xBFの範囲しか使わない(図03)。このため、エラーなどにより第一バイトが失われても、1文字のみを失うだけで済む。これは、文字列の途中を見たとしても、次の文字から正しくコードを判断できることを意味する。

  • 図03: UTF-8は、ユニコード文字をエンコードすることを前提に、バイト単位で自己同期ができるように作られたエンコード方法。第一バイトと第二バイト以降のパターンが一致しないようになっている

UTF-8の第一バイトは、半角片仮名後半の0xC2~0xDF、Shift JISの第一バイト0xE0~0xF4までと衝突している。このため、Shift JISの第二バイトの範囲がUTF-8の第二バイト以降と衝突しても、それぞれのルールから逸脱しないため、両者を完全に区別できない。Shift JISは、ユニコード制定以前から使われていて、日本中に大量のShift JISファイルが存在しており、互換性のためにいまさら仕様を変更することができない。なので、後から加わったUTF-8にBOMを付け、先頭で区別できるようにしたわけだ。

BOM(表01)には、ユニコード文字のU+FEFFが使われる。ここに含まれる0xFFは、無効なコードとして文字に割り当てないことが昔から行われてきた。Shift JISも0xFD~0xFF(および0x7F)を割り当てに使わない。このことからBOMをつければUTF-16/32とShift JISを混同する可能性はなくなる。

  • ■表01

UTF-8のBOMは、0xEF、0xBB、0xBFとなり、コード上は、Shift JISと一致するが、このパターンが先頭にあった場合にはUTF-8という判断を下す。0xEF、0xBBは、ユニコードのU+9B20という文字、0xBFは半角片仮名の「ソ」であり、通常のShift JISテキスト先頭には登場しない文字の組み合わせと割り切ったのであろう。このようにすることで、少なくとも自動処理を行う場合などにShift JISをUTF-8と誤解する可能性は低くなった。しかし、逆にWindows外から持ち込まれたBOMなしのUTF-8はShift JISと仮定されてしまうため、文字化けすることがある。著名なExcelのテキストファイル文字化けはこれが原因である。

2019年に登場したWindows 10 Ver 1909では、メモ帳のデフォルトコードをBOMなしのUTF-8に変更した。マイクロソフトとしても、そろそろShift JISを終わらせたかったのであろう。厳密な区別は困難だが、日本語の場合、平仮名、片仮名など、登場頻度の高い文字は、Shift JISコードの第一バイトが、UTF-8の第一バイトの範囲外になるため、区別が可能になる可能性は低くない。漢字表示が可能になって半角片仮名の利用は減ってきており、これもUTF-8と誤認する可能性を低下させている。

今回のタイトルネタは、「博士の異常な愛情」で知られる1964年のスタンリー・キューブリック監督作品“Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb”である。“BOM”と聞くと、ついつい、この“Bomb”を思い出してしまう。キューブリックの懐の深さを感じさせる作品。