1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

文字化けはなぜ起きるのか——「暗号表のズレ」で文字コードの仕組みを完全理解

1
Posted at

こんにちは!ハンズオンラボ運営のわたるです。

CSVファイルをExcelで開いたら、日本語が「�」や意味不明な記号の羅列に化けてしまった——そんな経験はありませんか?

この記事では、この文字化けが起きる仕組みを、「暗号表のズレ」 というたとえで解説します。原因さえわかれば、慌てず落ち着いて対処できるようになります。


この記事を読むと、以下のことができるようになります

  • 文字コードがそもそも何のためにあるのか説明できる
  • 文字化けがなぜ起きるのか、仕組みから理解できる
  • 実際のトラブルにどう対処すればよいか見当がつく

文字コードとは何か——「文字と数字を対応させる暗号表」

コンピュータは、文字をそのまま保存しているわけではなく、内部的には全て数字(0と1の並び)として扱っています

「どの数字が、どの文字に対応するか」を決めた対応表文字コードです。

これは、**暗号文を作るときに使う「暗号表」**と同じ役割です。「Aという記号は1を表す」「Bという記号は2を表す」というように、あらかじめ決めておいた対応表に従って、文字と数字を行き来しているわけです。


文字化けとは何か——「違う暗号表で解読してしまった状態」

暗号文を送るとき、送り手と受け手が同じ暗号表を使っていなければ、正しく解読できません

これがまさに文字化けの正体です。「保存するときに使った文字コード」と「読み込むときに使おうとした文字コード」が食い違っていると、同じ数字の並びを、まったく別の文字として解釈してしまい、画面には意味の通らない記号の羅列が表示されてしまいます。


実際にコードで文字化けを再現する

Pythonを使って、実際に「暗号表のズレ」を再現してみます。

text = "こんにちは"

# UTF-8という暗号表で暗号化(エンコード)する
encoded_utf8 = text.encode("utf-8")
print("UTF-8でエンコードしたバイト列:", encoded_utf8)

# 正しい暗号表(UTF-8)で解読する
print("正しく解読:", encoded_utf8.decode("utf-8"))

# 違う暗号表(Shift_JIS)で解読しようとする
print("違う暗号表で解読:", encoded_utf8.decode("shift_jis", errors="replace"))
実行結果(イメージ):
UTF-8でエンコードしたバイト列: b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'
正しく解読: こんにちは
違う暗号表で解読: ���[縺ォ縺。縺ッ

同じ数字の並び(バイト列)でも、「UTF-8という暗号表」で解読するか「Shift_JISという暗号表」で解読するかによって、まったく違う文字として表示されることがわかります。これがまさに文字化けの発生メカニズムです。


なぜ複数の「暗号表」が存在するのか

「暗号表を1つに統一すればいいのでは」と思うかもしれませんが、実際には歴史的な経緯で複数の文字コードが並存しています。

これは、国や時代によって異なる暗号表が独自に発展してきたようなものです。日本語のWindows環境では長らくShift_JISが主流でしたが、現在は世界中の言語を1つの体系で扱えるUTF-8が広く使われるようになっています。


よくある文字化けの発生パターン

実務でよく遭遇する文字化けには、いくつかの典型パターンがあります。

パターン 原因 対処法
CSVをExcelで開いたら文字化け 保存時の文字コードとExcelの想定文字コードが不一致 文字コード指定でインポートし直す
Webページの文字化け HTMLのmeta指定と実際の文字コードが不一致 <meta charset="UTF-8">を明示する
メールの文字化け 送信側と受信側のメールソフトの文字コード解釈違い 文字コードを明示的に指定して送信する

「そもそも何の暗号表で保存されたファイルなのか」を確認せずに開こうとすることが、これらのトラブルに共通する根本原因です。


実際のコードで解決策を体験する

文字コードを明示的に指定して読み込むことで、文字化けを防ぐ例を見てみます。

# 文字コードを明示的に指定してファイルを読み込む
with open("data.csv", encoding="shift_jis") as f:
    content = f.read()
    print(content)

これは、「この暗号文は暗号表Aで書かれています」と、あらかじめ受け手に伝えておくようなものです。読み込む側が「正しい暗号表」を知っていれば、文字化けは起きません。


BOM:暗号表を明記した付箋

UTF-8のファイルには、**BOM(Byte Order Mark)**と呼ばれる、ファイルの先頭に付けられる特殊な印が使われることがあります。

これは、暗号文を送るときに、封筒の表に「この中身は暗号表Aで書かれています」という付箋を貼っておくようなイメージです。BOMがあることで、読み込み側は文字コードを推測しやすくなりますが、一方でBOMに対応していないソフトウェアでは、逆にこの付箋自体が余計な文字として扱われ、文字化けの原因になることもあります。「あった方が親切なはずが、時に仇になる」という、少し皮肉な性質を持つ仕組みです。


UTF-8とUTF-16の違い:同じUnicodeでも表現方法が違う

「UTF-8」と「UTF-16」は、どちらも世界共通の文字の集合であるUnicodeを扱う仕組みですが、実際にどう数字の並びに変換するかという表現方法が異なります

これは、同じ台帳(Unicode)を参照していても、暗号表への書き起こし方(エンコード方式)が複数存在しているようなものです。「Unicodeを使っているから安心」ではなく、UTF-8なのかUTF-16なのか、具体的なエンコード方式まで一致させる必要があるという点が、文字化けトラブルを防ぐ上での見落としがちなポイントです。


よくある勘違い:「UTF-8にすれば絶対に文字化けしない」わけではない

「とにかくUTF-8を使っておけば安心」と思われがちですが、保存時と読み込み時、両方で文字コードが一致していなければ、UTF-8であっても文字化けは起きます。重要なのは特定の文字コードを選ぶことそのものではなく、「保存時と読み込み時で、暗号表がきちんと一致しているか」を常に意識することです。


ビフォーアフター

【ビフォー】

  • 文字化け → 「なぜか時々起きる、原因不明の不具合」という認識
  • 文字コード → Shift_JISやUTF-8という名前は知っていたが、違いを説明できなかった
  • 対処法 → 文字化けが起きたら、なんとなく別の方法で開き直して運任せにしていた

【アフター】

  • 文字化け → 「保存時と読み込み時の暗号表が食い違っている」ことが原因だとわかった
  • 文字コード → 「文字と数字を対応させる暗号表」であり、複数の種類が並存していると理解した
  • 対処法 → 「そのファイルが何の暗号表で保存されているか」を確認してから開くようになった

まとめ

この記事では、文字化けが起きる仕組みを整理しました。

  • 文字コードは、文字と数字を対応させる「暗号表」のようなもの
  • 文字化けは、保存時と読み込み時で異なる暗号表を使ってしまうことで起きる
  • Shift_JISとUTF-8など、歴史的経緯で複数の文字コードが並存している
  • CSVやWebページ、メールなど、実務でよく遭遇する典型パターンがある
  • 文字コードを明示的に指定することが、文字化けを防ぐ基本的な対策になる
  • BOMは「暗号表を明記した付箋」だが、対応状況によっては逆に文字化けの原因にもなりうる
  • 同じUnicodeでも、UTF-8とUTF-16のようにエンコード方式が異なれば一致させる必要がある

次に文字化けに遭遇したら、「保存時と読み込み時で、暗号表がズレていないか」を確認してみてください。原因さえわかれば、慌てず対処できるようになります。


ハンズオンラボでは、未経験からでも「作って覚える」をモットーにしたITハンズオンイベントを定期開催しています。

👉 イベント一覧はこちら

運営メンバーのXはこちら
えむ / わたる


面白かったら
「👇いいね」で応援

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?