Windows 固有の文字エンコーディング問題

2 minute read

以前の記事で、日本社会全般の視点で日本語文字エンコーディングの新旧混在問題を解説しました。

「文字化け」はなぜ終わらない? 日本のITを縛る文字エンコーディングの深い闇

今回は、Windowsユーザーの視点で、この日本語文字エンコーディングの新旧混在問題について、解説したいと思います。

現代、Web界隈では完全に UTF-8 がテキストデータを支配しており、若い人を始め、十数年前から IT機器を使い始めたユーザーには、「なぜ、文字エンコーディングが問題になるのか」が理解できない人が増えていると感じます。
そもそも「なぜ、BOM付きUTF-8などという物が存在するのか」が分からない若者も多いのではないでしょうか。

「BOM付きUTF-8」は完全にWindows固有の問題であり、そして同時に無くては困るものでもあります。
また、これに関連してWindowsワールドでは古い文字エンコーディングに付随する形で、テキストの扱いが難しくなっている問題があります。
Linux や Mac OS には存在しない Windows 固有のテキスト問題を、ここに纏めておきたいと思います。

PC三大勢力

昔からPC規格には、今と同じ三大勢力が存在していました。
UNIX勢力、Apple勢力、Microsoft勢力です。
今は、それぞれ Linux OS、Mac OS、Windows に収まっていますが、少し昔は UNIX規格には様々なOSが存在し、Apple PC の OSは現在の Mac OS とは規格の異なるOSを採用していました。
Windowsが登場する前は、MS-DOS が Microsoftの主力OSでした。
それぞれの勢力の日本語対応もバラバラで、日本語圏においては、今より互い勢力圏の間でのテキスト交換が困難な状況でした。

昔の三大勢力のテキスト規格

1990年代から2005年頃までのPC三大勢力のテキスト規格

OS勢力圏 日本語文字エンコーディング 改行コード規格
UNIX系各種OS EUC-JP LF
Apple System7 等 旧OS Shift_JIS CR
Microsoft DOS\&Windows Shift_JIS CR・LF

Unicode 規格が普及し始めたのは、2000年代中盤頃からなので、この時代に UTF-8 も UTF-16 もPCでは使用されていません。
1990年前後から2005年までで15年です。その前後5年ぐらいを加えて25年ぐらいの期間は、この古いテキスト規格で、企業や官公庁でテキストデータが作成されてきたということです。
そのデータ蓄積の大きさを想像してみてください。

2000年代のテキスト規格の革新

2000年代は、三大勢力全般にOS全般の革新が起こり、同時にテキスト規格も様変わりしました。

OS 規格の革新

UNIX勢力の中に Linux OS が台頭し始め、Web Server を中心に急激に普及しました。
これにより、他のUNIX系OSは存在感を急速に失い、UNIX系の規格を採用したOSとしては、Linux OS がデファクトスタンダードのような存在になっていきました。
(ちなみに Linux は正式な UNIX ではありませんが、ほぼ UNIX と考えて差し支え無い規格の OSカーネルです)

Apple は、当初からモトローラーのCPUを採用していましたが、その性能がインテルCPUに対して劣っていたため、Apple社は Mac のCPUをインテルCPUに変更し、それに伴って Mac の OS を、それまでの System 7 系統から UNIX規格の Mac OS に変更しました。
これに伴い、Mac の テキスト規格も UNIX規格に変更されました。

Microsoft は UNIX勢力や Apple より、PC市場では後発だったため、当初 MS-DOS を投入するとき、既に作られていた UNIXやApple旧OS のテキストデータを読み込める規格にする必要がありました。
米国では、テキストコードは ASCII で統一されているので、ここは問題ありませんが、改行コードは UNIX は LF、Apple旧OS は CR とバラバラだったので、どちらの改行にも対応できるように CR・LF を改行コードに定めました。
Microsoft は最初からインテルCPUを採用していたので、現在に至るまで OS 自体の規格変更は行っていません。WindowsはMS-DOSのテキスト規格を継承しています。

Unicode の台頭

2000年代は、米国以外の各国において文字エンコーディングが古いものから Unicode 規格の文字エンコーディングへ切り替わった時代でした。
当初、Unicode の文字エンコーディングは、UTF-16 が主流でしたが、その後 UTF-8 が登場して現代では、UTF-8 が世界標準の文字エンコーディングとなりました。
ちょうど、三大勢力のOS が、古いものから新しいものへと、切り替わるタイミングと一致した影響も大きいと思われます。

今の三大勢力のテキスト規格

OS勢力圏 日本語文字エンコーディング 改行コード規格
Linux OS (GNU Linux) UTF-8 (BOM 無し) LF
Apple Mac OS UTF-8 (BOM 無し) LF
Windows UTF-8 (BOM 付き) CR・LF

Windows は、旧 Windows PowerShell など、一時 UTF-16LE を採用していた時期がありますが、最新の PowerShell7 などでは UTF-8 を採用しています。
また、OS や ファイルシステムや DBMS の内部では、UTF-16 が今でも活用されています。
.NET や JavaVM の内部も UTF-16 を使用しています。

現代では、ユーザーの目に触れる部分では、テキスト規格は UTF-8 にほぼ統一されています。

今では Windows 規格だけが孤立している

元々、Windows規格 は UNIX のテキストも Mac のテキストも読めるように作られた規格ですが、後の世でMacとLinuxの革新が、UTF-8とUNIXテキスト規格に統合された事により、Windowsだけが孤立したテキスト規格を採用している状態になってしまいました。

これは、Microsoft社が悪いわけではなく、「運が悪かった」としか言いようがありません。

Windows - 早く普及した弊害

プログラマーでもハッカー(コンピュータのヘビーユーザー)でもない、一般ユーザーに早く普及したOSは Windows です。
Windows 95 以降は、急激に「普通の人」がPCを利用するようになりました。
一方、この時代は、UNIXはまだ高価なワークステーションでしか利用できない状態で、Linuxはカーネルの初期バージョンが登場したばかりで、本格的ディストリビューションの普及はまだまだ先の話でした。
Apple の Mac は Windows との競争に苦戦していた時期で、時々 iMac などヒット商品を出していましたが、Windows 95 以降の Microsoft の躍進に比べると、地味な存在で「一部のマニアの使うPC」という位置づけでした。
企業や公的機関で本格的に採用されていたのは、Microsoft Windows でした。

そのような背景があるため、社会で次々作成されるテキストデータは、大半が Windows 規格のテキストでした。文字エンコーディングが Shift_JIS で、改行コード CR・LF のデータが量産されていったのです。

Linuxが本格的に普及し始めたのは、2000年代で、既に Unicode の時代に変わっていました。
Apple Mac は 2000年代に、障害となっていた モトローラーCPU の性能問題を克服するためにインテルCPUへ切り替え、同時に UNIX OS に更新したため、同時に Unicode 規格に変更しました。
もともと企業や官公庁に大きく普及していたわけではないので、経路依存性の障害は小さく、過去のテキスト規格を事実上放棄して、UNIX 規格に全面切り替えました。

Microsoft Windows は企業や官公庁に広く普及しており、ユーザーのデータ資産を守る責任を無視できない立場にありました。
時代のテキスト規格が、Unicode に切り替わる局面において、最も経路依存性の障害が大きかったのは、Microsoft Windows と言えると思います。
Windows の普及が他のOSに比べて早かったことによる弊害と言えるでしょう。

過去データを捨てられない

Windows においては、古いテキスト規格のデータだけでなく、古いテキスト規格を使用する古いソフトウェアが大量に存在します。
これらのソフトウェアの Unicode 規格への更新は、日本社会においてはまだ完了していません。
古いソフトウェアは、今でも古いテキスト規格のデータを量産しています。

過去の古いデータの蓄積量も膨大で、全てのデータの Unicode への変換は不可能なケースも少なくないです。

また、Windows には短期間ではありますが、UTF-16LE を Unicode 標準として採用した時期があり、そのとき作られた UTF-16LE テキストも古いテキストデータとして残っています。
今でも Windows PowerShell の標準文字エンコーディングは UTF-16LE です。

Windows 環境では、しばらくの間は古いテキスト規格と、新しいテキスト規格を共存させる必要があります。
その新旧テキストの共存を実現するために必要になったのが「BOM付きUTF-8」です。

Windows の古いテキスト文字エンコーディングは、Shift_JIS です。
Shift_JIS のテキストと、UTF-8、 UTF-16LE のテキストを、各アプリケーションが識別できなければなりません。
しかし、Shift_JIS と UTF-8 と UTF-16LE を、予備情報無しで識別するのは難しく、完全な信頼性で識別するのは不可能と考えて良いです。
文字エンコーディングを識別するソフトウェアは、バイナリパターンから文字エンコーディングを高確率で「推測」しているだけで、100%確実な文字エンコーディング・バイナリパターン推測の方法は存在しないのです。

BOM問題

Microsoft も完全な識別を保証できない文字エンコーディング・バイナリパターン推測に依存するわけにはいきませんから、確実に Shift_JIS と UTF-8 と UTF-16LE を識別できる手段を採用しています。
その手段が BOM です。

BOM とは、Byte Order Mark の略で、テキストファイルの先頭に Unicode のエンコーディング種類を示すマークを付けて、そのテキストがどのUnicode文字エンコーディングかを識別する仕組みです。

Unicode には、5つの文字エンコーディングが存在し、Unicode 標準化委員会がそれぞれを区別するために定めた、Unicode の標準規格です。Microsoft の独自規格ではありません。
BOMは、文字として扱われない短いバイナリパターンです。
5つの文字エンコーディングとそれぞれのBOMのバイナリパターン(16進数の数値)は、以下の表のように対応しています。

文字エンコーディング BOMのバイナリパターン(16進数) BOMの長さ(バイト数)
UTF-8 EF, BB, BF 3バイト
UTF-16 LE FF, FE 2バイト
UTF-16 BE FE, FF 2バイト
UTF-32 LE FF, FE, 00, 00 4バイト
UTF-32 BE 00, 00, FE, FF 4バイト

Windows のテキストファイルでは、UTF-8 と UTF-16LE のテキストファイル先頭に、このBOMが付加されています。
Excelで、Unicode の CSV を保存すると、CSVファイルの先頭に {EF,BB,BF} のBOMが書き込まれます。
Excelでは「通常のCSVファイル保存」を行った場合は、今でも Shift_JIS で保存されます。当然 BOM は付きません。(Shift_JIS の BOM という規格は存在しません)

この仕様は、ユーザーにとって文字化けなど様々なトラブルの原因になっています。

ExcelのCSV保存は、典型的なWindows経路依存性問題の中心的存在です。

LE(Little Endian)・BE(Big Endian)とは

ちなみに、LE とか BE というのは、CPUがメモリから数値を読み込むときに、1バイトづつ読み込むわけですが、現代は64ビット(8バイト)CPUの時代なのでCPUの扱う整数値も64ビット(8バイト)になります。
バイト単位で数値を読み込むとき、8バイトの数値をメモリから読み込むことになりますが、このとき8バイトのCPUレジスタ(CPU内の記憶領域)へ、メモリの先頭からバイト単位でコピーすることになります。このコピーを8バイトのレジスタの「先頭から後ろのバイトへの順番」に書き込むのか、「後ろから前のバイトへの順番」に書き込むのか、CPUの仕様によって異なります。
前者をBE(Big Endian)、後者をLE(Little Endian)と呼びます。
文字エンコーディングのLEやBEとは、CPUのLEに合わせた文字エンコーディングです。
インテルやARMはLE、昔のモトローラーCPUやJavaVMはBEで作られています。
インターネットもBEを標準としています。
このLE(Little Endian),BE(Big Endian)については、深く理解する必要はありません。「文字エンコーディングの種類が違う」とだけ理解してください。

WSL採用の弊害

2010年代には、ソフトウェア開発者の多くが Linux ベースで開発を行うようになりました。
Docker、Node.js、Python、Rubyなど、モダンな開発ツールはLinux環境で最も快適に動作する上に、開発者がLinuxネイティブなコマンドラインツール(bash, grep, awkなど)を使えないと、Windowsから離れて、Linuxへ移ってしまうため、MicrosoftはWindows上でLinux開発環境を使える WSL (Windows Subsystem for Linux) を、2017年頃から導入しました。
WSLを使用すると、Windows上のファイルをLinuxで直接閲覧編集することができるようになります。

しかし、逆にWindows 上で Linux が使用できるようになったことにより、Windows上のPowerShellやエディタなどでも Linux の「BOM無しUTF-8」テキストファイルを扱う必要性が出てきました。
また、GitHUBを買収したことにより、オープンソース系のLinuxテキストファイルの読み書きも、できなければならなくなりました。こちらも「BOM無しUTF-8」テキストファイルを扱わなければならない要因です。

Microsoft社がLinuxを初めとしたOSS界を肯定したことにより、「BOM無しUTF-8テキスト」と「LFのみの改行コード」を無視できなくなったのです。

「メモ帳」が「BOMなしUTF-8」に対応

2019年5月のWindowsアップデートから、標準の「メモ帳」が「BOMなしUTF-8」のテキストファイルに対応しました。世界標準に合わせる為です。

これにより、LinuxやMac由来のUTF-8テキストファイルの文字化けは、格段に減少したそうですが、逆に古いShift_JISテキストは文字化けが、Windows環境で頻発するようになったようです。

当たり前です。

現在のWindows環境は、テキストファイルに関しては、BOMの有無だけでは、Shift_JISなのかUTF-8なのか明確にならない中途半端な状況になっており、レガシーなシステムを扱っている企業や自治体・官公庁、そして金融機関に医療機関などでは、メモ帳がアテにならない状態になっています。
メモ帳で、Shift_JISもUTF-8もUTF-8-BOMも全て開けますが、Excelは「BOM無しUTF-8」のCSVを開くと文字化けします。

むしろ、昔の秀丸やサクラエディタの方が日本語文字エンコーディング・改行コード・BOMの判別機能を持っているので、安全かも知れません。

現状のWindowsは、「Shift_JISとUTF-8テキストファイルの違いとBOMの有無・改行コード種類」の区別を、以前よりもユーザーが自己責任で識別しなければならない面倒な時代になっています。

Mac OS と Linux系OS には存在しない問題

既に解説していますが、Mac OS と Linux系OS には、この Shift_JIS と UTF-8 が混在する問題も、改行コードCR・LFとLFの混在問題も、「UTF-8のBOMの有無」問題も存在しません。
Mac OS と Linux系OS では、文字エンコーディングはUTF-8のBOM無し、改行コードはLFのみ、で統一されています。
過去の歴史的経緯から運悪く、Windows環境だけで面倒くさい状況になっているのです。

標準的な対策ツール

テキストファイルの文字エンコーディングと改行コードやBOMの有無を、調べたり変更したりするツールは、昔からいくつか存在します。
昔は、Windowsのシェアが圧倒的だったので、文字エンコーディングと改行コードやBOMの有無の問題に晒されるのは、UNIXやMacの側である事が多かったようです。
そのため、この問題の対策ツールも、主要なものはUNIX環境で開発されています。

代表的なツールは、file , iconv , nkf というコマンドツールです。
file と iconv は、UNIX系シェルでしか使用できません。PowerShell や cmd では使えません。
Windows環境で使用するならば、WSLでWindowsの領域を参照して、bashでfileとiconvを使用するか、Git Bash をインストールして、Bash上で fileとiconvを使用するのが、簡単確実な方法です。
ただし、iconv は日本語の推測精度があまり高くないようです。
fileは文字エンコーディングに対処するツールではなく、改行コードの確認と変換に使用できるツールです。

PowerShell でも文字エンコーディングの変換はできますが、文字エンコーディングの確認手段がありません。
また、多くの場合、PowerShell ではいちいちスクリプトを組まなければ、文字エンコーディングと改行コードやBOMの有無に対処することができないケースが多く、手軽さに欠けるのが現実です。

nkfコマンドは例外的に、PowerShell や cmd で使用できますが、nkfもUNIX標準で開発されているコマンドツールで、ワイルドカード展開はシェル任せで、Windows上では使用できません。
また、PowerShellのオブジェクトパイプラインに対応していませんから、nkfの特徴であるリダイレクトによる文字エンコーディングの変換機能などが使えません。
nkfの開発者は初めからUNIXに合わせて開発しているので、PowerShellに合わせる動機は無いでしょう。

つまり、残念ながらWindowsユーザーは、問題の震源地であるWindows環境では、問題を解決する多くのツールが使用できないという、非常に不幸な状況に陥っています。

Windows環境で、対象ファイルが一つ二つ程度ならば、昔から存在している秀丸エディタやサクラエディタが文字エンコーディング確認機能と、改行コード・BOMの確認機能を持っており、それぞれの変換も可能なので、便利だと思います。
UNIX環境ならnkfがワイルドカードで一括処理ができるので便利ですが、Windows環境のPowerShellとcmdでは、ワイルドカードが使えません。一つずつファイルを処理するなら、昔のエディタの方が良いでしょう。
Windowsならば、個人が開発しているシェアウェアに良いツールが沢山あると思います。

先日、私がリリースしたOSSツール(MITライセンス)も、この問題を解決するツールです。
PowerShellとcmdで動作します。
逆に、UNIX環境には合わせていません。
PowerShellとcmdの標準に合わせて開発しています。
複数ファイルを一括で処理できます。
文字エンコーディング確認機能と、改行コード・BOMの確認機能、それぞれの編集機能を持ちます。

rmsmf-txprobe & mfsr-mfprobe 使い方の分かりやすい解説

既存ツール類に満足できなければ、試してみてください。

将来予測

MicrosoftはWSL導入以降、テキストファイルの扱い方で迷走しているように見えます。

「メモ帳など一部だけBOM無しUTF-8に対応している」この状況は、主にLinux系開発環境を使用している開発者には、好ましいかも知れませんが、レガシーデータやレガシーシステムを扱っているエンジニアには、面倒な上に「どっちつかず」の中途半端で対処に困る状況ではないでしょうか。
現在の状況は、「テキスト文字エンコーディングの判別はユーザーの自己責任」という、かなり無責任な状況と言えます。

元々、Microsoftは、当初OSSに対して懐疑的な姿勢を示していましたが、2017年頃から戦略を大きく転換し、OSSへの対応を強化してきました。

メモ帳が「BOM無しUTF-8」に対応したこと、その理由は「世界標準に合わせるため」という、この状況から将来のMicrosoftの方針を予測すると、誰が予測しても「WindowsはUNIX標準テキストに合わせる」という将来が見えてきます。

UNIX標準テキストとは既に説明したように、「文字エンコーディングは UTF-8 、改行コードは LF のみ、UTF-8テキストの先頭にBOMは付けない」という仕様です。

もし、Windows標準テキストがUNIX標準に従うことになれば、現在のWindows標準である「BOM無しテキストはShift_JIS、BOM付きテキストはUnicodeエンコーディング、改行コードはCR・LF」というテキスト仕様は、丸ごと「古いレガシー」となってしまいます。

注意して欲しい点として、UNIX標準に合わせたところで、「古いレガシー」が消えてなくなるわけではないことです。
Windows環境では、今でもShift_JISのテキストが現役であり、大量のレガシーデータとして健在であるように、これまで20年近く作成されてきた「BOM付きUTF-8テキストとCRLF改行」は、丸ごと新たな「古いレガシー」として、全てのWindows環境に横たわります。
ITエンジニアは、「Shift_JISテキスト」「BOM付きUTF-16LEテキスト」に加えて「BOM付きUTF-8テキスト」と「CR・LFの改行」のお守りをしなければならなくなります。

現在でも、Excel が Shift_JISのCSV を吐き出し続けるように、UNIX標準をMicrosoftが採用したとしても、古いアプリや互換性を重視する多数のアプリや業務システムが、「BOM付きUTF-8テキスト」と「CR・LFの改行」を10年以上は吐き出し続けることになるでしょう。

Windowsユーザーの大多数は文字エンコーディングやBOMの問題など理解しようともしません。
Shift_JISからUTF-8-BOMへ、そしてUTF-8-BOM-CRLFからUTF-8-LFへ、と二段構えでのテキスト規格変更が行われれば、Windowsしか使わないユーザーの間でも、テキスト規格に関連するトラブルが続出することは避けられないと思われます。

現在のMicrosoftは、テキスト規格の方針を明確にしていません。
今の「BOM無しUTF-8テキストLF改行」の受け入れ方は、非常に中途半端な姿勢に見えます。
今は中途半端ですが、将来は十中八九でUNIX標準テキストが採用されると思います。
それがいつになるのかは、分かりませんが、十年もかからないでしょう。

CR改行の古いMacは、もう存在しません。
ITの合理性から考えて、現代のUTF-8テキストの「BOMとCR」は邪魔な代物なので、MicrosoftがUNIX標準に合わせるのは、時間の問題でしょう。

一応、将来のその事態に備えておいた方が良いかも知れません。

Updated: