【新卒向け】文字コードとエンコーディング入門 - 文字化けはなぜ起きる?
文字化けはなぜ起きるのかを、文字コードとエンコーディングの仕組みから新卒エンジニア向けにやさしく解説し、Pythonでファイルのエンコーディングを確認・変換する安全な手順までを紹介します。
開いたCSVが「譁�蟄怜喧縺�」になる朝
取引先から届いたCSVファイルをExcelで開いたら、顧客名の欄が「譁�蟄怜喧縺�」のような記号の羅列になっていた。中身は壊れていないはずなのに、文字だけが読めない。新卒で現場に入ると、多くの人が最初の数週間でこの場面に出くわします。これが俗に言う「文字化け」です。
文字化けは、ファイルやデータが壊れて起きるわけではありません。ほとんどの場合、データ自体は無傷で、ただ「読み方」を間違えているだけです。この記事では、なぜ読み方を間違えると文字が化けるのかを、文字コードとエンコーディングという2つの仕組みから順に解きほぐしていきます。
文字コード — コンピュータは文字を番号で扱う
まず大前提として、コンピュータは文字そのものを理解しません。扱えるのは数値だけです。そこで「どの文字をどの番号に対応させるか」を決めた巨大な対応表が必要になります。これを 文字コード(または文字集合、character set)と呼びます。
身近なたとえで言えば、座席表のようなものです。「A1番の席は田中さん、A2番は佐藤さん」と決めておけば、席番号を伝えるだけで誰のことか分かります。文字コードも同じで、「65番はA、12354番は『あ』」というように、文字へ番号を割り当てた表です。この番号のことを コードポイント(符号位置)と呼びます。
世界には複数の対応表が存在します。アルファベットと記号だけを定めた古い表が ASCII(アスキー)で、0〜127番の128文字しかありません。これに日本語や中国語、絵文字まで含め、世界中の文字を一つの表にまとめようとしたのが Unicode(ユニコード)です。現在のWebやプログラムはほぼUnicodeを前提に作られています。
つまずきポイント:「文字コード」と「エンコーディング」を同じ意味だと思ってしまう
新卒のうちは、この2語を混同しがちです。文字コードは「文字と番号の対応表」でした。次に説明するエンコーディングは「その番号を、実際にファイルへどう書き込むか」という別の話です。表と、表の保存方法。役割が違うことを先に押さえておくと、この後がぐっと分かりやすくなります。
エンコーディング — 番号をバイトの並びに変換する規則
文字コードで「あ」が12354番だと分かっても、まだ問題が残ります。ファイルに保存できるのは バイト(0〜255の値を取る、データの最小単位のかたまり)の列だけです。12354という番号を、どういうバイトの並びとして書き出すか。そのルールが エンコーディング(符号化方式)です。
同じUnicodeの番号でも、バイトへの変換方法は何種類もあります。代表的なものを挙げます。
- UTF-8:1文字を1〜4バイトの可変長で表す方式。アルファベットは1バイト、日本語は3バイト程度。現在の世界標準で、迷ったらこれを選びます。
- Shift_JIS(シフトジス):Windowsの日本語環境やExcelのCSVで古くから使われてきた方式。日本語を2バイトで表します。
ここが文字化けの核心です。保存するとき(エンコード)と読み込むとき(デコード)で、別々のエンコーディングを使うと、同じバイト列をまったく違う文字として解釈してしまいます。冒頭の「譁�蟄怜喧縺�」は、UTF-8で保存された日本語を、Shift_JISだと思い込んで読んだときに典型的に現れる化け方です。バイトは正しく届いているのに、変換表だけがすれ違っている状態です。
つまずきポイント:Excelで開くと化けるからデータが壊れていると思い込む
ExcelはCSVをShift_JIS前提で開くことがあり、UTF-8のファイルだと化けます。しかし同じファイルをテキストエディタでUTF-8指定で開けば、正しく読めます。「アプリによって見え方が変わる」なら、データ破損ではなくエンコーディングのすれ違いを疑うのが先決です。
操作 — エンコーディングを確認してから変換する
仕組みが分かったところで、実際の確認と変換に進みます。ここで使うのは Python 3 です。多くの環境に最初から入っており、OSを問わず同じコードが動きます。ターミナル(コマンドプロンプトやシェル)から実行します。
まず「何のエンコーディングか」を推定する
変換の前に、相手のファイルがどのエンコーディングかを知る必要があります。chardet というライブラリで推定できます。
# Install the detection library first
pip install chardet
import chardet
# Read the file as raw bytes, not as text
with open("customers.csv", "rb") as f:
raw = f.read()
# Let the library guess the encoding from the byte pattern
result = chardet.detect(raw)
print(result) # e.g. {'encoding': 'SHIFT_JIS', 'confidence': 0.99, ...}
このコードの読み方です。ポイントは open の第2引数の "rb"で、これは「バイトとして」読む指定です。エンコーディングがまだ分からない段階で文字として読もうとすると、その時点で化けたり失敗したりするため、あえて生のバイトのまま受け取っています。detect はバイトの並び方のクセから推定し、encoding(推定した方式)と confidence(確からしさ、0〜1)を返します。あくまで推定なので、confidence が低いときは結果を鵜呑みにしない姿勢が大切です。
読み込みと書き出しで、それぞれ正しい方式を指定する
エンコーディングが分かれば、変換は「正しい方式で読み、別の方式で書く」だけです。ここではShift_JISのCSVをUTF-8に変換します。
# Read with the encoding it was actually saved in
with open("customers.csv", "r", encoding="shift_jis") as f:
text = f.read()
# Write a new file with the target encoding
with open("customers_utf8.csv", "w", encoding="utf-8") as f:
f.write(text)
読み方のコツは、encoding= を読み込み側と書き出し側の両方で明示している点です。Pythonは encoding を省略すると実行環境の既定値を使うため、環境が変わると挙動も変わります。省略は文字化けの温床なので、常に書くクセをつけてください。変換は元ファイルを上書きせず、customers_utf8.csv という新しい名前で保存しています。
つまずきポイント:読めてしまうが、実は一部だけ化けている
Shift_JISとして読んでもエラーが出ず、しかし一部の文字だけ化けることがあります。読み込み時に errors="strict" を付けると(これは既定の動作です)、解釈できないバイトに出会った時点で例外を投げて止まります。黙って別の文字に置き換えるより、止まって気づけるほうが安全です。異常を握りつぶさないことが、データを扱う仕事の基本姿勢になります。
安全な習慣 — 元ファイルを壊さずに変換する
現場でエンコーディング変換を行うとき、プロが必ず守る習慣があります。元のファイルを直接上書きしないことです。上の例で別名保存したのは、このためです。
変換は一方向ではうまくいかないことがあります。推定を誤れば、変換後のファイルはさらに激しく化けます。元ファイルが手元に残っていれば、方式を変えて何度でもやり直せます。上書きしてしまうと、化けた状態からは元に戻せません。「取り返しのつかない操作の前に、元を残す」。これはエンコーディングに限らず、データを扱うあらゆる場面で効いてくる考え方です。
まとめ
今日の内容を、頭の中のイメージとして整理しておきます。
- 文字コードは「文字と番号の対応表」。座席表のように、文字へ番号を割り当てたもの(ASCII、Unicodeなど)。
- エンコーディングは「番号を実際のバイト列へ変換する規則」。同じUnicodeでもUTF-8やShift_JISなど複数ある。
- 文字化けは、保存時と読み込み時でエンコーディングがすれ違って起きる。データ破損ではなく「読み方」の問題。
- 変換は、正しい方式で読み、別の方式で書くだけ。ただし
encodingは必ず明示し、元ファイルは上書きしない。
次の一歩として、今日のうちに手元のテキストエディタ(VS Codeなど)で、適当なファイルを開いて画面の端にある文字コード表示を探してみてください。多くのエディタは現在のエンコーディングを常に表示し、クリックで切り替えられます。「今このファイルは何で読まれているのか」を意識する習慣が、文字化けに動じない第一歩になります。
※ この記事はAIが自動生成したものです。本記事の内容は執筆時点の情報であり、正確性を保証するものではありません。ご利用の際は免責事項をご確認ください。
Related / 関連記事
関連記事
Azureクラウド入門 - 主要サービスの全体像を掴む
Azureを初めて学ぶ若手エンジニア向けに、クラウドの考え方からリソースグループ、計算・保存・通信・認証の主要サービス、Azure CLIでの実践までを全体像として整理して解説します。
【新卒向け】セキュリティの基本 - パスワード管理と多要素認証
新卒エンジニアに向けて、パスワードの仕組みと危険性、パスワードマネージャーの使い方、多要素認証の考え方を、日常の場面から順を追って解説する入門記事です。
【新卒向け】ネットワーク基礎 - IPアドレスからDNSまで
ブラウザがサーバーに繋がらない場面を入り口に、IPアドレスやポート番号、そして名前を住所へ変換するDNSの仕組みを、身近な例えとすぐ試せるコマンドで新卒エンジニア向けに丁寧に解説します。
Comments / コメント