文字エンコーディングとは? 解説
文字エンコーディングとは、文字を、テキストの保存と伝送に使うバイトへ、そしてその逆へと対応づけるスキームです。
コンピュータはすべてをバイトとして保存しますが、人間は文字を読みます。文字エンコーディングは、その両者を結ぶ取り決めです。どのバイトがどの文字を意味するのか。ファイルの書き手と読み手がエンコーディングで合意していれば、テキストは完璧に往復します。食い違えば文字化けが起こります - 最も一般的で紛らわしいCIの失敗の1つです。
文字エンコーディングとは
文字エンコーディングは双方向の対応づけです。書くときは文字からバイトへ、読むときはバイトから文字へ。ファイルを正しく読むには、プログラムは書くのに使われたのと同じエンコーディングを使わなければなりません。さもなければバイトを誤って解釈します。
文字セットとエンコーディング
文字セット(Unicodeなど)は、文字の一覧と、それぞれに割り当てられた番号です。エンコーディング(UTF-8やUTF-16など)は、その番号をバイトに変える具体的な規則です。1つの文字セットは複数のエンコーディングを持ちうるため、両方の情報が重要になります。
レガシーエンコーディングとmojibake
Unicode以前は、多くの地域的エンコーディングが存在しました - Latin-1、Windows-1252、Shift-JIS - それぞれが限られた文字集合をカバーしていました。あるエンコーディングで書かれたファイルを別のものであるかのように読むと、「mojibake(文字化け)」、つまり出力に時々見かける崩れたアクセント付き文字が生じます。
CIにおけるエンコーディング
CIはデフォルトlocaleが異なりうるマシンをまたいで実行されるため、ローカルでは動くjobが、runnerがソースファイルを読む際に別のエンコーディングを仮定するというだけの理由でCIで失敗しうります。環境でエンコーディングをpin固定すれば、この種の非決定性がまるごと取り除かれます。
# 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固定します。