コピーしただけのファイルなのに「一致しません」と言われる。開いて見比べても、目で追っても、差が見つからない。
目で見えないのは当たり前です。違っているのは「文字として表示されない部分」だから。原因はだいたい2つに絞れます。
⚠️ この記事の情報は2026年8月時点のものです。筆者のシステムは相場を観測・研究するためのもので、自動発注はしません(read-only)。実際のお金での発注はしていません(仮想発注のみ・実発注なし)。環境やツールの仕様は変わるため、内容は随時更新します。
この記事で分かること
結論から。「中身は同じなのに一致しない」の犯人は、ほぼ次のどちらかです。
- BOM(ボム)=ファイルの先頭に付く、画面に表示されない印(byte order mark)
- 改行コード=行の終わりを表す記号。WindowsのCRLFとMac/LinuxのLFで違う
どちらも「文字を1文字も書き換えていないのに、バイト列は別物になる」タイプの違いです。人間の目には同じ、機械には別物。この段差にハマると、原因を探す方向が最初から間違います。
【早見表】症状→原因→確認手順
まずここだけ見れば当たりが付きます。
| 症状 | 疑うべき原因 | 最初に見るところ |
|---|---|---|
| 先頭の列名だけ文字化けする(1列目のヘッダーだけ変な記号が付く) | ファイル先頭のBOM | 保存時の文字コードが「UTF-8(BOM付き)」になっていないか |
| 1行も直していないのに差分が「全行変更」になる | 改行コードがCRLFとLFで食い違っている | エディタ右下の改行表示(CRLF / LF) |
| 中身は同じに見えるのにファイルサイズやハッシュ値が違う | 改行コードの違い、またはBOMの有無 | 行数とバイト数の差が対応していないか |
| 読み込みが黙って0件になる/対象から外れる | 先頭のBOMで解析が拒否されている | エラーではなく「スキップ」扱いになっていないか |
| 日本語を表示しようとした瞬間だけ落ちる | コンソール側の文字コード(Windows日本語環境のcp932) | 出力先の文字コード設定 |
BOMとは何か
BOM(byte order mark)は、ファイルの先頭にだけ置かれる「このファイルはUTF-8です」という目印です。UTF-8では3バイト分。エディタで開いても表示されません。
厄介なのは、ソフトによって扱いが割れること。「あってもいい」と読むソフトと、「文法違反」として弾くソフトがあります。読み飛ばす側ばかり使っていると、存在に気づかないまま何年も過ごせてしまう。
BOMが付く保存操作
- Excelで「CSV UTF-8」形式として保存したとき
- エディタの文字コード指定を「UTF-8(BOM付き)」のまま保存したとき
- ファイルを書き出すスクリプトが、BOM付きを既定にしているとき
「自分で付けた覚えがない」のが普通です。付けたのは保存操作のほうなので。
付いているかの確認手順
- エディタで見る:VS Codeなら右下に文字コードが出ます。「UTF-8 with BOM」ならBOM付き。クリックでBOMなし保存に直せます。ただしBOMを外す前に、そのファイルの使い道を確認してください。ExcelでCSVを直接開く前提のファイルは、BOMを外すと日本語が文字化けすることがあります(BOMを手がかりにUTF-8と判別しているため)。BOMなしにそろえるのは、プログラムやツールで読み込む・比較するファイルに限るのが安全です
- PowerShellで先頭バイトを覗く:
Format-Hex -Path ファイル名 | Select-Object -First 1を実行し、先頭がEF BB BFで始まっていればBOM付きです
改行コード(CRLF / LF)とは

行の終わりを表す記号にも流派があります。WindowsはCRLF(2バイト)、Mac/LinuxはLF(1バイト)。同じ文章でも、行の終わりごとに1バイトずつ差が出ます。
表示上は完全に同じ。だからこそ、差分ツールが「全行が変わりました」と言い出すと理由が分からなくなります。
中身が同じでもバイト数が変わる=自環境の実測
筆者の環境で実際に測った数字です(他の環境で同じ差になるとは限りません)。
- ある監査記録のテキスト:LF形で10,827バイト、CRLF形で10,901バイト。差は74バイトで、これはこのファイルに含まれる74回分の改行がLFからCRLFへ変わった量とちょうど一致しました
- ある決裁記録のJSON:LF形で2,402バイト、CRLF形で2,426バイト。差は24バイトで、24回分の改行と一致
確認手順3ステップ

「一致しない」と言われたら、この順で見ます。
- ステップ1:バイト数を並べる。PowerShellなら
(Get-Item ファイル名).Length。2つの数字を書き出し、差が何バイトかをメモします - ステップ2:差の正体を当てる。差が3バイトならBOMの可能性が高い。差が行数に近い数字なら改行コードの可能性が高い。どちらでも説明が付かないときは、中身そのものの違いに加えて、行末の余分な空白・全角空白・ゼロ幅スペースといった別の見えない文字や、文字コード自体(UTF-8とShift_JISなど)の違いも疑います
- ステップ3:エディタで裏を取る。VS Codeの右下で「文字コード」と「改行コード(CRLF / LF)」を確認し、2つのファイルで食い違っていないかを見ます
ステップ2で答えが出ることがほとんど。中身を1行ずつ見比べるのは、この3ステップで説明が付かなかったときだけで足ります。
比べる前にそろえる4手順
原因が分かったら、次は再発させない置き方です。順番が大事。
- ①基準を先に決める。「保存はUTF-8(BOMなし)、改行はLF」のように、迷わないルールを1行で書き留める
- ②保存側をそろえる。エディタの既定設定を変え、書き出すスクリプトの文字コード指定も明示する
- ③比べる前に変換する。BOMを外し、改行を基準の形に直してから比較。このとき元のファイルは直接書き換えず、コピーを作ってそちらを変換する(バージョン管理下なら変換前に必ずコミットしておく)。一括変換は、まず1ファイルで結果を確かめてから広げます。この一手間を前処理として固定する
- ④判定の入口を1か所にする。複数の経路でチェックしているなら、そろえる処理を共通化する。経路ごとに書くと片方だけ直して片方が残ります
④は地味ですが効きます。筆者も当初は片方の経路だけを直す計画でしたが、途中で気づいて両方を同じ処理に通しました。
実録:見えない1文字が4ファイルを検査から消していた2日間の時系列
ここからは筆者の記録です。題材は株の値動きを観測するために個人開発しているシステムで、相場を観測・研究するためのもの。自動発注はしません(read-only)。実際のお金での発注はしていません(仮想発注のみ・実発注なし)。
解析が拒否して黙って除外=検査は赤いのに理由が見えない
8月6日。その日のうちに追加した4つのファイルが、すべてBOM付きで保存されていました。Pythonでソースを文字列として読み込み、構文解析(ast.parse)にかける仕組みは、先頭のBOMを受け付けません。結果、リポジトリ全体を走査する仕組みはその4ファイルを「解析エラー」として記録し、検査対象から外していました。
表に出ていたのは「3つのテストが赤い」という事実。ファイルを開いても中身は正しく見える。当然です、違いは表示されない先頭3バイトなのだから。
BOMを外した瞬間に別の不具合が表面化した
BOMを取り除いてファイルが検査対象に戻った途端、その下に隠れていた2つ目の問題が出てきました。2つの検査ツールが、判定結果のJSONを「日本語をそのまま出す」設定で表示していたのです。
Windows日本語環境のコンソール(cp932)では、これが文字コードのエラーになります。しかも落ち方が悪い。判定結果と終了コードを同時に失うため、合格だったのかすら残りません。
対処は、他のツールで既に使っていた安全な出力処理へ寄せること。まず日本語のまま出し、だめなら記号表記へ(情報は落ちません)、それでもだめなら生バイト列へ、と段階的に落とす形です。判定のロジックには触れていません。結果も両方とも合格のままでした。
詰まった箇所と回避策
翌8月7日、同じ根っこの問題が別の形で出ました。ファイルが差し替えられていないかを確認する照合が、作業フォルダに置かれた状態のバイト列を基準にしていたのです。
Gitには取得時に改行コードを自動変換する設定があります。同じ内容でも、取ってきた場所によってバイト列が変わる。実際、片方の作業フォルダでは合格、新しく取得し直したフォルダでは17件が不合格と、判定が反転していました。中身は一つも書き換わっていません(27件すべてで内容一致を確認)。
回避策は、比較前に「そろえる」規約を1つ決めること。UTF-8として厳密に読み、BOMを外し、CRLFと単独のCRをLFに畳んでから照合する。ポイントは2つ。
- 照合の経路が2つあったので、両方を同じ関数に通した。片方だけ直すと、同じファイルが「どちらの経路で検査されたか」で別判定になります
- 検出力は落とさない範囲にとどめた。吸収するのは改行の書き方とBOMの有無だけ。本文が1文字でも変われば従来どおり不一致になります。読めない形式や未知の指定は、合格に倒さず不合格にしました
同じ日、電子署名の検証でも同じことが起きていました。検証に渡す材料が作業フォルダのバイト列だったため、取得場所によって「署名が正しい/正しくない」が入れ替わる。前述の2,402/2,426バイトの実測はこのときのものです。既存の署名はLF形に対して作られていたと分かり、検証側の入り口をそろえるだけで済みました。
よくある失敗
失敗1:除外リストを広げて合格にしてしまう
「このファイルだけ検査から外せば全部緑になる」。一番手が伸びやすく、一番危ない選択肢です。緑になった画面は、問題が消えた証拠ではなく見なくなった証拠でしかない。筆者の場合、外したのは除外リストではなくBOMによる自動スキップでしたが、結果は同じでした。検査から外れていた4ファイルの下に不具合が2つ眠っていました。
失敗2:エラーが出ないから正常だと判断する
BOMがらみの一番いやらしい点はここ。派手に落ちてくれず、「読み込みました、0件でした」と静かに返ってきます。件数がゼロ・対象が空は「異常なし」ではなく「何かがおかしい」のサインとして扱うほうが安全。件数を毎回確認する習慣のほうが、エラーを待つより早く気づけます。
非エンジニアが得た教訓
- 「同じに見える」は「同じ」ではない。表示されない部分にこそ差が入る。目視は証拠にならない
- 黙って外されるものが一番危ない。赤いエラーより、静かなスキップのほうが長く生き残る
- 直したら次が出るのは正常。1つ目を取り除いたから2つ目が見えた。前進の合図です
- そろえてから比べる。比較の前処理を決めておけば、同じ迷子を繰り返さずに済みます
まとめと次に読む
中身が同じなのに一致しないとき、まずバイト数の差を見る。3バイトならBOM、行数分なら改行コードのことが多い。そのどちらでも説明が付かなければ、中身や他の不可視文字を疑う。
ただし、BOMを外せばどんな不一致も解消するわけではありません。筆者の環境でも、外した先にまた別の問題が出てきました。ここで書いたのは自分の環境での記録と、そこから作った確認の順番です。同じ症状でも原因は環境によって変わります。
それでも「見えないものを疑う」発想を一度持てたかどうかで、次の時間の使い方は変わります。CSVを扱う場面が多い方は、マーケットスピード2 RSSの使い方のようなデータ取り込み作業でも同じ落とし穴が待っています。
関連記事
- エラーが出たときの直し方ガイド — メッセージから原因にたどり着く手順
- AI開発でやらかした失敗まとめ — 「静かに壊れる」系のつまずき集
- マーケットスピード2 RSSの使い方 — 表データを扱う前提の基本操作
無料テンプレート配布のお知らせ
Claude Codeを安全・便利に使うための設定テンプレート(CLAUDE.md)を無料配布しています。メールアドレスをご登録いただくと、すぐにダウンロードリンクをお送りします。
免責事項
本記事は執筆時点(2026年8月)の情報に基づく、筆者個人の体験の記録です。記事中の自動売買システムに関する記述は、特定の投資手法や自動売買の利用を推奨するものではありません。投資には元本割れのリスクがあり、最終的な判断はご自身の責任で行ってください。また、本記事ではセキュリティに関わる話題に触れていますが、悪用防止の観点から、具体的な脆弱性や攻撃手法の詳細は記載していません。AIツールの仕様は予告なく変更される場合があります。最新情報は各公式ドキュメントをご確認ください。本記事の内容を用いて生じたいかなる損害についても、筆者は責任を負いかねます。


コメント