Windows の文字コードと改行コードを整理する - Shift_JIS / UTF-8 / UTF-16、文字化け、CRLF / LF、なぜ混乱するのか

· · Windows, 文字コード, 文字化け, 改行コード, UTF-8, CP932, PowerShell, Unicode

最初に押さえるべきこと

テキストファイルは 「文字列」そのものではなく、「バイト列 + 文字コード + 改行コード」 です。BOM が付くこともあります。

トラブルのほとんどは、以下のいずれかです。

  1. 同じバイト列を別の文字コードとして読んだ → 文字化け
  2. 行区切りの前提がずれている → 改行トラブル(文字コードは合っているのに)
  3. 誤読した内容をそのまま保存した → データ破損(元に戻せない)

この3つを区別するだけで、原因特定の速度が大幅に変わります。

用語の整理 ── まず言葉のズレを直す

同じ「あ」でもバイト列は異なる

文字: あ

UTF-8     : E3 81 82
CP932     : 82 A0
UTF-16LE  : 42 30

文字とバイト列は別物です。事故はこの変換の境界で起きます。

Windows でよくある言葉の罠

言葉 実際の意味 注意
ANSI そのマシンのアクティブコードページ(日本語環境では CP932) ASCII ではない。環境依存
Unicode(メニュー表記) UTF-16LE を指すことが多い 「Unicode で保存」= UTF-16LE かも。UTF-8 とは限らない
Shift_JIS 口語では CP932 を指すことが多い Linux 側の shift_jis とは厳密には異なる
UTF-8N UTF-8 no BOM のこと(エディタ独自ラベル) 正式名称ではない
text 人によって前提が違う 仕様では「UTF-8 no BOM, LF」のように具体化すべき

ラベルのズレが混乱を生む: 会話では通じているように見えても、実体は揃っていません。

文字化けの正体 ── シンプルな仕組み

元の文字列 → encoding A でバイト化 → encoding B で文字列に戻す → 前提不一致 → 文字化け
  • UTF-8 の「あ」(E3 81 82) を CP932 として読む → など別の文字に見える
  • この時点ではまだバイト列は壊れていない(読み方を間違えただけ)
  • 危険なのは: 壊れて見えている内容を そのまま保存 すること → 元のバイト列が失われる

表示崩れ vs データ破損

段階 状態 復旧可能性
UTF-8 ファイルを CP932 で開いただけ 表示が崩れているがバイト列は元のまま 復旧可能(正しい文字コードで開き直す)
崩れた内容を保存した バイト列が別のものに書き換わった 原則復旧不可

改行コード ── 文字コードとは別問題

改行もバイトです。

改行 バイト列 主な環境
CRLF 0D 0A Windows の従来テキスト、レガシーツール
LF 0A Linux / macOS / モダンな開発ツール
CR 0D 旧 Mac(現在はほぼ登場しない)

重要なのは、文字コードと改行コードは独立していること です。

UTF-8 + LF       : 41 0A 42          ← "A\nB"
UTF-8 + CRLF     : 41 0D 0A 42       ← "A\r\nB"
CP932 + LF       : ありえる
UTF-16LE + CRLF  : ありえる

「UTF-8 にしたのにまだ違う」→ 文字コードは合っているが改行だけがずれているケースが多い。

なぜ Windows では特に混乱しやすいのか

1. Unicode とコードページが共存している

Windows には以下の複数のテキスト文化が同居しています。

  • UTF-8(モダン、Web、クロスプラットフォーム)
  • CP932(レガシー CSV、TXT、ログ、業務システム連携)
  • UTF-16LE(一部の API、アプリ内部表現)

1 台の Windows の中に3つの前提が混在している。

2. ツールが暗黙に前提を変える

作業者が明示しなくても、次の層が勝手に前提を足してきます。

  • エディタの自動判定(auto-detect)
  • 保存時の BOM 自動付与 / 除去
  • Git の CRLF ↔ LF 自動変換(core.autocrlf
  • コンソールのコードページ(chcp
  • PowerShell のバージョン別デフォルトエンコーディング
  • CSV エクスポートの想定外コードページ

「何も変えていないのに壊れた」の正体は、ツールの既定値が変わったこと。

3. ASCII 範囲だと問題が隠れる

UTF-8 は ASCII と互換性があるため、英数字だけのファイルは「たまたま読める」状態になります。日本語が1行入った瞬間に発火します。

よくある事故パターン

場面 ずれているもの 症状
UTF-8 no BOM のファイルをレガシーツールで開く 読む側が CP932 と誤判定 日本語だけ文字化け
CP932 の CSV を UTF-8 前提の処理系に渡す 読む側の前提違い 、デコードエラー
UTF-16LE のログを Unix 系ツールに渡す エンコーディング違い NUL バイト混入、バイナリ扱い
LF のソースファイルが別環境で CRLF に変換される 改行前提の違い 巨大な行末差分、シェルスクリプト不具合
文字化けを見たあと保存してしまう バイト列が別物に データ破損、復旧不可
仕様を「CSV」としか書かない インタフェース未定義 Excel では読めるが他ツールで壊れる

実務で事故を減らす 6 つのルール

1. 新規ファイルの基準を決める

「UTF-8」だけでは不十分。最低限ここまで決めます。

  • BOM あり / なし
  • 改行は CRLF / LF
  • 読む側は何か(レガシー Windows ツールか、Linux / CI も使うか)
用途 推奨
クロスプラットフォームのソースコード UTF-8 no BOM, LF
Windows 専用のレガシーツール連携 UTF-8 with BOM, CRLF または CP932
Excel で開く CSV UTF-8 with BOM, CRLF

2. 既存ファイルは勝手に変えない

  • 日常の小修正のついでに UTF-8 化しない
  • エンコーディング変換は 別タスク として切り出す
  • 変換前に下流コンシューマを確認する

3. 仕様を具体的に書く

悪い例: 「CSV で出力」
良い例: 「UTF-8 with BOM, CRLF, カンマ区切り, ヘッダー行あり」

4. コードでエンコーディングを明示する

  • ファイル読み書き時にエンコーディングを指定する(暗黙のデフォルトに任せない)
  • プロセス間のテキスト受け渡しでもエンコーディングを意識する
  • シェルの雑なリダイレクトを本番経路にしない

5. Git とエディタの設定を共有する

  • .gitattributes で改行の扱いを固定する
  • エディタの改行・エンコーディング設定をチームで共有する
  • Git は改行を揃えてくれても、エンコーディング事故はそのまま残る

6. 報告の仕方を変える

悪い報告 良い報告
「文字化けしました」 「UTF-8 no BOM のファイルを CP932 前提で開いているように見えます」
「行末がおかしいです」 「LF のファイルが CRLF に変換されて差分が増えています」

「何がずれたか」が言えるだけで調査速度が大幅に上がる。

調査のための 5 つの質問

文字化けや行末トラブルで迷ったら、この5問に答えます。

  1. このファイルのバイト列は何か(UTF-8 / UTF-8 with BOM / CP932 / UTF-16LE)
  2. 誰がどの前提で書いたか(エディタ / レガシーアプリ / Excel エクスポート / スクリプト)
  3. 誰がどの前提で読んでいるか(エディタの自動判定 / コンソールのコードページ / ライブラリのデフォルト)
  4. BOM はあり / なし、改行は CRLF / LF か
  5. 誤読した内容がすでに保存されたか(表示だけか、バイト列が失われたか)

この5問が埋まると、たいてい原因は見えてきます。

まとめ

Windows の文字コードがややこしく見えるのは、日本語が難しいからではありません。

バイト列 + エンコーディング + BOM + 改行 + ツールの既定値 が別々に存在し、その上で新旧のテキスト文化が同居しているからです。

覚えておくこと 詳細
文字化けの原因 同じバイト列を別のエンコーディングで読んだ
改行は別問題 文字コードが合っていても CRLF / LF の不一致は起こる
言葉を信用しすぎない 「ANSI」「Unicode」「Shift_JIS」はツールごとに意味が違う
UTF-8 だけでは不十分 BOM と改行コードまで決めて初めて運用ルールになる
表示崩れ ≠ データ破損 保存する前に開き直せば復旧できる可能性がある
仕様は具体的に 「text」ではなく「UTF-8 no BOM, LF」と書く

参考資料

関連する記事

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

Windows×Linux間の文字化けを根本解決する

Windows と Linux の間で起きる文字化けを、バイト列の解釈ずれという観点で整理する記事です。CP932・UTF-8・UTF-16、コンソール code page、PowerShell の版差を踏まえ、調査の進め方と運用ルールがわかります。

記事を読む

Windows × Codex の文字化け防止ガイド

Windows で Codex に日本語ファイルを扱わせると文字化け事故が起きやすい原因を整理し、読み込み前の確認、保存条件、再読込検証、AGENTS.md への常設ルールまで、現場で再利用できる指示テンプレートを提示します。

記事を読む

関連トピック

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

このテーマがつながるサービス

この記事は次のサービスページにつながります。近い入口からご覧ください。

ブログ一覧に戻る