Skip to content
Latchkey

文字エンコーディングとは? 解説

文字エンコーディングとは、文字を、テキストの保存と伝送に使うバイトへ、そしてその逆へと対応づけるスキームです。

コンピュータはすべてをバイトとして保存しますが、人間は文字を読みます。文字エンコーディングは、その両者を結ぶ取り決めです。どのバイトがどの文字を意味するのか。ファイルの書き手と読み手がエンコーディングで合意していれば、テキストは完璧に往復します。食い違えば文字化けが起こります - 最も一般的で紛らわしいCIの失敗の1つです。

文字エンコーディングとは

文字エンコーディングは双方向の対応づけです。書くときは文字からバイトへ、読むときはバイトから文字へ。ファイルを正しく読むには、プログラムは書くのに使われたのと同じエンコーディングを使わなければなりません。さもなければバイトを誤って解釈します。

文字セットとエンコーディング

文字セット(Unicodeなど)は、文字の一覧と、それぞれに割り当てられた番号です。エンコーディング(UTF-8やUTF-16など)は、その番号をバイトに変える具体的な規則です。1つの文字セットは複数のエンコーディングを持ちうるため、両方の情報が重要になります。

レガシーエンコーディングとmojibake

Unicode以前は、多くの地域的エンコーディングが存在しました - Latin-1、Windows-1252、Shift-JIS - それぞれが限られた文字集合をカバーしていました。あるエンコーディングで書かれたファイルを別のものであるかのように読むと、「mojibake(文字化け)」、つまり出力に時々見かける崩れたアクセント付き文字が生じます。

CIにおけるエンコーディング

CIはデフォルトlocaleが異なりうるマシンをまたいで実行されるため、ローカルでは動くjobが、runnerがソースファイルを読む際に別のエンコーディングを仮定するというだけの理由でCIで失敗しうります。環境でエンコーディングをpin固定すれば、この種の非決定性がまるごと取り除かれます。

Pinning encoding in a job
# Make a Python build encoding-deterministic in CI
env:
  PYTHONUTF8: "1"
steps:
  - run: python generate_docs.py

再現性にとって重要な理由

再現可能なbuildは、どこでも同一の出力を生むべきです。エンコーディングは隠れた入力です。同じソースでも、異なるエンコーディングで読むと異なるバイトを生みうります。エディタ、ファイル、CIのあらゆる場所でUTF-8に標準化すれば、このドリフトの原因が排除されます。

重要なポイント

  • 文字エンコーディングは文字をバイトへ、そして逆へと対応づけます。読み手と書き手が合意する必要があります。
  • 文字セットは文字の一覧であり、エンコーディングはそれらがどうバイトになるかです。
  • CIのエンコーディングバグはマシン間のlocaleの違いから生じます - 決定的なbuildのためにUTF-8をpin固定します。

関連ガイド