ASCII
American Standard Code for Information Interchange
概要(サマリー)
ASCII(アスキー)とは、アルファベット・数字・記号を7ビットの数値で表す、最も基本的な文字コード規格である。
1963年にアメリカで制定された古い規格だが、現在使われているほぼすべての文字コードがこのASCIIを土台にしている。そのため「文字コードの共通の祖先」と考えるとよい。
扱えるのは128種類だけで、日本語は1文字も入っていない。それでも、プログラミング言語のキーワード、HTMLのタグ、URL、設定ファイルなど、開発の現場で目にする文字の多くはASCIIの範囲に収まっている。
詳細解説
ASCIIとは何か(128個だけの対応表)
ASCIIは、0から127までの128個の数値に対して、1つずつ文字を割り当てた対応表である。128種類は7ビットで表現できる。
内訳はおおまかに次のとおりである。
0〜31: 制御文字(改行、タブなど画面に表示されない文字)32〜47など: 記号(スペース、!、+、/など)48〜57: 数字の0〜965〜90: 大文字のA〜Z97〜122: 小文字のa〜z127: 削除を表す制御文字
数字の 0 が48番、大文字 A が65番、小文字 a が97番、という3つだけ覚えておくと、実務で見当をつけやすくなる。
大文字と小文字がちょうど32違う
ASCIIの並びには意図的な規則性がある。大文字 A(65)と小文字 a(97)の差はちょうど32であり、これは2進数で見ると6桁目のビットが1つ違うだけである。
A= 65 =1000001a= 97 =1100001
そのため、古いプログラムでは「32を足す・引く」あるいは「ビットを反転する」だけで大文字小文字を変換していた。現在は言語の標準機能を使うべきだが、この規則性を知っているとビット演算の理解が進む。
コードで確認してみる
文字とASCII番号の相互変換は、どの言語でも簡単に確認できる。
JavaScriptの場合は次のように書く。
console.log("A".charCodeAt(0)); // 65
console.log("a".charCodeAt(0)); // 97
console.log(String.fromCharCode(65)); // "A"
Pythonでは ord() と chr() を使う。
print(ord("A")) # 65
print(chr(97)) # 'a'
「文字を番号に変える」「番号から文字を作る」という発想は、Unicodeでもそのまま通用する。ASCIIはその最も単純な形である。
制御文字という「見えない文字」
ASCIIの0〜31番は、画面に表示されない制御文字である。もともとは通信機やプリンタを操作するための命令だった。
現在も重要なのは次の2つである。
10(LF, Line Feed): 改行13(CR, Carriage Return): 行頭復帰
WindowsとMac・Linuxで改行コードが異なる(Windowsは CR+LF、Mac・Linuxは LF)のは、この2つの使い方の歴史的な違いによる。Gitで差分が意図せず全行に出てしまうトラブルの原因になることがある。
見えない文字であるため、コピー&ペーストで紛れ込むと発見しづらい。「見た目は正しいのに動かない」ときは、制御文字の混入を疑う価値がある。
ASCIIから拡張へ、そしてUnicodeへ
ASCIIは128種類しかなく、英語以外の言語を表現できない。そこで各国が「余った8ビット目」を使って独自に拡張した。
日本ではShift_JISやEUC-JPが作られ、ヨーロッパではまた別の拡張が使われた。この「各国がバラバラに拡張した」ことが、後の文字化け問題の根本原因である。
同じバイト列でも、どの拡張規格で読むかによって別の文字になってしまうためである。この混乱を根本から解決するために作られたのがUnicodeであり、その符号化方式であるUTF-8は、ASCIIの範囲(0〜127)についてはASCIIと完全に同じバイト列になるよう設計されている。
この後方互換性のおかげで、英数字だけのファイルはASCIIとして読んでもUTF-8として読んでも同じ結果になる。逆に言えば、日本語を含むファイルでだけ文字化けが起きるのはこのためである。
AIコーディングとの関係
AIにコードを書かせるとき、ASCIIの範囲を意識させると事故を減らせる。特に、識別子・ファイル名・URLに日本語や全角記号が混ざると、環境によって動かなくなることがある。
たとえば次のように指示するとよい。
アップロードされたファイル名を安全な形式に変換する関数を書いてください。
ファイル名はASCIIの英数字とハイフン・アンダースコアのみに制限してください。
日本語が含まれる場合は除去ではなく、別途IDを振って元の名前を保持してください。
また、AIが生成したコードをそのまま貼り付けると、全角スペースやスマートクォート(" ではなく “)が混入してエラーになることがある。これらはASCII外の文字であり、見た目では気づきにくい。
構文エラーの原因が分からないときは、「このコードにASCII外の文字が含まれていないか確認してください」とAIに尋ねるか、エディタの不可視文字表示機能を使うとよい。
よくある勘違い
ASCIIは日本語も扱える?
扱えない。ASCIIは128種類しかなく、アルファベット・数字・記号・制御文字だけである。日本語を扱うには、Shift_JISやUTF-8といった別の文字コードが必要になる。
ASCIIは古い規格なのでもう使われていない?
現役である。UTF-8はASCIIと後方互換性を持つよう設計されており、英数字部分のバイト列はASCIIと完全に一致する。HTML、URL、プログラミング言語のキーワード、設定ファイルの多くは今もASCIIの範囲で書かれている。
半角文字なら何でもASCII?
違う。半角カタカナはASCIIには含まれない。日本独自の拡張として後から追加されたものであり、環境によって文字化けしやすい。半角だからASCIIとは限らない点に注意する。
1文字は必ず1バイト?
ASCIIの範囲であれば1文字1バイトだが、これはあくまでASCIIとUTF-8の英数字部分に限った話である。UTF-8では日本語は3バイト、絵文字は4バイト使うことが多く、「1文字=1バイト」という前提でプログラムを書くと文字が途中で壊れる。
まとめ
- ASCIIは、英数字と記号を7ビット(128種類)で表す最も基本的な文字コード規格である
- 数字の
0は48、大文字Aは65、小文字aは97から始まる - 0〜31番は画面に表示されない制御文字で、改行コードの違いもここに由来する
- 各国がASCIIを独自に拡張したことが、文字化け問題の根本原因になった
- UTF-8はASCIIと後方互換性があるため、英数字だけのファイルは化けない