ASCIIと文字コードの舞台

ここまでの講で組み立ててきたのは、すべて数を表すビット列だった。2進数、BCD、 マシンコード——コンピュータのメモリはビットしか保存できないので、扱いたいものはすべてビットの形に しなければならない。では次に扱うものは何か。この世界の情報の大半は、テキストの形で蓄積されている。 テキストをビットで表すには何が必要か。実はこの問いに、私たちはすでに一度答えている ——第1講のモールス符号と点字である。この講は、そこからボードーコード、ASCII、そしてUnicodeへと続く 「文字をコードにする」系譜を辿り直す。全5セクション・演習22問。回答はブラウザに保存されるので、 途中でやめても続きから再開できる。

進捗 0 / 22 問(正解 0 問)

1. 固定長コードへの道 — ボードーコードとシフトコードの限界

コンピュータのメモリはビットしか保存できない。数もマシンコードもビットで表す方法を見てきたが、この世界の情報の大半はテキストの形で蓄積されている。テキストをビットで表すには、各文字に唯一のコードを対応させる体系——コード化文字セット——を決めなければならない。この問いに、私たちは第1講ですでに一度答えている。モールス符号は頻度によって長さが変わる可変長コード、点字は6ビットの固定長コード。そして1874年にエミール・ボードーが作った5ビットコードは、32通りしか作れない枠の中に文字も数字も記号も詰め込むために、レターシフトとフィギュアシフトという2つの特別なコードで意味を切り替える方式を採った。この方式が抱える弱点が、次のセクションのASCIIを呼び寄せることになる。

テキストをデジタル形式で表すには、まず各文字に唯一のコードを対応させる体系を作らな ければならない。文字だけでなく、数字も句読点も単語間の空白も、それぞれコードを必要とする。この ような体系はコード化文字セットと呼ばれ、個々のコードは文字コードと 呼ばれる。

ここで、問題をいったん単純にしておこう。私たちは本や雑誌の紙面に整然と組まれたテキストに慣れて いるが、その体裁はテキストそのものにとって本質ではない。同じ文章を、段の幅が違う紙面で読んでも、 書体が違っていても、内容が変わったとは思わない。だからテキストを2次元に配置されたもの としてではなく、文字・数字・句読点・段落の区切りが一列に並んだ1次元の記号列として 捉え直す。斜体も太字も色も、いったん脇に置く。

こう捉え直すと、第1講で扱ったモールス符号と点字が、 すでに同じ問いに答えていたことが見えてくる。ただし両者の性格は違う。モールス符号は、よく使う文字 ほど短い符号を割り当てる可変長のコードで、電信には適しているがコンピュータでは 扱いにくい。一方の点字は6つの点、つまり6ビットの固定長コードであり、この点では コンピュータ向きである。ただし点字も大文字と数字を表すのに、「次の文字は大文字である」「ここから 数字である」と合図する特別なコードを必要とした。

1874年、フランス電信局の役人だったエミール・ボードーが印字電信のために作った 5ビットコードは、この「特別なコード」の考え方を体系の中心に据えたものだった。後にドナルド・マレーが 手を加え、1931年に国際的な標準として正式化される。米国では通称ボードーとして知られ、 20世紀のテレタイプライタで広く使われた。

しかし5ビットでは32通りしかコードが作れない。アルファベット26文字を割り当てただけでほぼ埋まって しまう。そこでボードーは、フィギュアシフトレターシフトという2つの 特別なコードを用意した。フィギュアシフトの後に続くコードはすべて数字や句読記号として解釈され、 レターシフトが現れると再び文字として解釈される。同じビット列が、直前のシフトコードによって別の文字 を意味する仕組みである。

この方式には典型的な弱点がある。シフトコードは「以降の解釈モードを切り替える」だけの合図なので、 途中の1個が欠けたり誤読されたりすると、それ以降のテキストがすべて誤ったモードで解釈され 続ける。同じデータ列を続けて2回送ると、2行目の先頭が前回の最後のシフト状態を引きずって 数字として印字されてしまう、というような事故が起きる。数字にも文字にも専用のコードを与えておけば、 こういう連鎖的な誤読は起こらない——次のセクションのASCIIは、まさにその道を選ぶ。

文字コード体系のビット幅比較横軸は本コースに登場した順。縦軸は1文字あたりのビット数481216ビット可変長モールス符号可変長(頻度で長さが変わる)6ビット点字64通り5ビットボードー32通り7ビットASCII128通り16ビットUnicode(初期・16bit)65,536通り※これは書籍刊行当時の初期仕様。現在はU+10FFFFまで拡張され、符号化(UTF-8/UTF-16)は可変長点字(6)からボードー(5)へいったん低くなるのは登場順に並べたため。ビット数が単調に増えてきたわけではない
演習 1理解

テキストをビットの形でコンピュータに保存するために、最初に決めなければならないことは何か

演習 2理解

モールス符号・点字(第1講)とボードーコード(5ビット・32通り)を比べたとき、ボードーコードが点字と共通して持つ性質はどれか

演習 3理解

ボードーコードは32通りしかコードを作れないのに、文字・数字・記号のすべてを表現できる。これを可能にしている仕組みはどれか

演習 4理解

シフトコードを使う方式には、ある典型的な弱点がある。それはどれか

演習 5計算

ボードーコードは5ビットのコードである。5ビットで表現できるコードの総数はいくつか

このセクション: 0 / 5 問正解

2. ASCIIの設計 — 7ビット・128種のコード構造

シフトを使わずに大文字・小文字・数字・句読記号のすべてに専用のコードを与えるには何ビット必要か。大文字と小文字で52個、数字で10個、これだけで62個になり、句読記号を足せば6ビットの64通りを超えてしまう。答えは7ビット——128通りには十分な余裕がある。ここで登場するのが、1967年に制定された情報交換用米国標準コード、すなわちASCIIである。00hから7Fhまでの128個のコードは、制御文字・記号と数字・大文字・小文字という4つのブロックにきれいに分かれ、アルファベットは連続したコードに並ぶ。大文字と対応する小文字のコードがちょうど20h違うという規則性は、ビット操作だけで大文字と小文字を変換できるという実用的な恩恵をもたらす。

シフトコードに頼らず、大文字・小文字・数字・句読記号のすべてに専用のコードを与えるには、何ビット 必要だろうか。実際に数えてみればよい。大文字と小文字で52個、0から9までの数字で10個——これだけで すでに62個になる。ここにいくつか句読記号を足せば64個を超え、6ビットでは足りない。 では次の7ビットはどうか。128通りには、まだかなりの余裕がある。答えは7ビットである。

あとはコードの割り当てを決めるだけだが、自分だけのコンピュータを作って他とつながずに使うのでない 限り、独自のコードには意味がない。テキスト情報をやり取りするには、多くの人が同じコードに 合意する方が合理的である。そして割り当ては無秩序であってはならない。アルファベットが連続 したコードに並んでいれば、並べ替えや分類がコード値の比較だけで済むからである。

この基準はすでに作られている。情報交換用米国標準コード、略して ASCII——1967年に正式に決定された7ビットのコードである。00hから7Fhまでの128個の コードを持ち、今もコンピュータ業界で最も重要な標準であり続けている。

ASCIIの128個は、32個ずつ4つのブロックに分けて眺めると構造がつかみやすい。

  • 00h〜1Fh: 制御文字。目に見えないが、それぞれ特定の機能を持つ
  • 20h〜3Fh: スペース・句読記号・数字の0〜9
  • 40h〜5Fh: 大文字のA〜Zと、いくつかの記号
  • 60h〜7Fh: 小文字のa〜zと、いくつかの記号

この構造には、もう1つ見逃せない規則性がある。大文字と、対応する小文字のコードは、ちょうど 20hだけ違う。たとえば大文字「M」が4Dhなら、小文字「m」は6Dhである。差が常に一定という ことは、その差にあたる1ビットを立てたり落としたりするだけで大文字と小文字を行き来できるという ことでもある。実際、値DFhとのビットごとのAND演算という1命令だけで、小文字を大文字に変換できる。

文字コードの並べ方という、一見すると事務的な取り決めの中に、並べ替えの効率と変換の手軽さが あらかじめ埋め込まれている。ASCIIが半世紀を超えて生き延びてきた理由の一端は、この設計の 気配りにある。

ASCIIコード表の4ブロック構造7ビット=128個のコードを、32個ずつ4つのブロックに分けて眺める00h 〜 1Fh制御文字目に見えない(CR・LF・タブ等)20h 〜 3Fh記号・数字スペース・句読記号・0〜940h 〜 5Fh大文字A〜Z(と一部の記号)60h 〜 7Fh小文字a〜z(と一部の記号)細い区切り=1個のコード(1ブロックあたり32個)41h =「A」61h =「a」+20h大文字と対応する小文字のコード差は常に20h。ビット操作だけで大文字と小文字を変換できる

このコード割り当てを、下のシミュレータで手元から確かめよう。入力欄に文字を打つと、各文字の 文字コードが16進と2進で1つずつ並ぶ。同じアルファベットの大文字と小文字を両方入れるか、 「大文字⇄小文字」ボタンで一斉に切り替えると、両者の差がちょうど20h——2進ではビット1つ分—— であることが観察できる。

さわって確認文字コード分解 — 打った文字がASCIIのコードになる

4文字 / 最大16文字(1文字 = 7ビットのコード)

C43h
o6Fh
d64h
e65h

同じアルファベットの大文字と小文字(例: C と c)を両方入力すると、ペアがハイライトされます。

キーを1つ打つたびに、その文字に割り当てられた7ビットのコードが1つ増えていきます。英字の2進表示で ピンク色の枠が付いているのが20h(=32)の位のビットで、大文字と小文字はこの1ビットしか 違いません。「大文字⇄小文字」を押すと全部の英字が一斉に入れ替わりますが、変わっているのは 各文字のこのビットだけ——並べ替えも大小変換もコードの計算だけで済むという、ASCIIの設計の気配りを 指先で確かめてみてください。

演習 6理解

ASCIIとは何の略称か、また何ビットのコードか

演習 7計算

ASCIIは7ビットのコードである。7ビットのコードで区別できる組み合わせの総数はいくつか

演習 8理解

ASCIIでアルファベットの文字に連続したコードを割り当てることには、どのような利点があるか

演習 9理解

ASCIIの128個のコードは、00h〜1Fh・20h〜3Fh・40h〜5Fh・60h〜7Fhの4つのブロックに分けて見ることができる。この4ブロックの内容として正しい組み合わせはどれか

演習 10計算

ASCIIでは、大文字と対応する小文字のコードはちょうど20h(2進数で0010 0000)だけ違う。大文字「M」のASCIIコードが4Dhのとき、小文字「m」のASCIIコードはどれか

このセクション: 0 / 5 問正解

3. 制御文字とテキストの中の数字

ASCIIの128個のコードは、目に見える95個のグラフィック文字と、目に見えないが機能を持つ33個の制御文字に分かれる。キャリッジリターンとラインフィードはタイプライタの2つの動作をそのまま受け継いだもので、新しい行に移るには通常その両方が必要になる。そして本講で最も注意したいのが、文章の中に現れる数字の扱いである。テキスト中の数字は、その数値を表す2進数でもBCDでもなく、「数字という文字」に割り当てられた文字コードで表される——同じ数がどのビット列になるかは文脈が決める。最後に、ASCIIが抱える米国偏重という限界を確認して、次のセクションの拡張へ橋を渡す。

ASCIIの128個のコードのうち、目に見える表現を持つものは95個ある。これらは グラフィック文字と呼ばれる。残る33個は制御文字——画面や紙に姿を 現さないが、それぞれ特定の機能を果たすコードである。ASCIIが作られた当時は主にテレタイプライタでの 使用が念頭にあったため、今日ではほとんど使われなくなったものも少なくない。

制御文字の役割は、テレタイプライタやプリンタのような装置がコード列に反応して紙に文字を印字して いく様子を思い浮かべると理解しやすい。装置の通常の動作は「文字を印字して、印字位置を右に1つ動かす」 である。制御文字は、この通常の動作を変更する。水平タブは次の文字の印字位置を決まった間隔の位置まで 飛ばし、改ページは現在のページを排出して新しいページを始める。

中でも重要なのがキャリッジリターンラインフィードである。どちらも タイプライタの動作に由来する。行末に達したとき、タイプライタは2つのことを行った——印字位置を紙の 左端に戻すことと、紙を1行分送ること。前者がキャリッジリターン、後者がラインフィードで、ASCIIでは それぞれ独立した制御文字になっている。新しい行に移るには、通常この両方が必要である。 キャリッジリターンだけを使えば同じ行に重ねて印字でき、ラインフィードだけを使えば左に戻らずに次の 行へ進める。

もう1つ、本講で最も注意したい区別がある。文章の中に現れる数字の扱いである。たとえば「12歳」の 「12」をASCIIでコード化するとき、これは12という数値ではなく、「1」と「2」という 2つの文字として扱われる。数値としての2進表現でも、BCDコードでもない、数字1と数字2 それぞれに割り当てられた文字コードが使われる。

同じ「12」という数が、文脈によってまったく別のビット列になる——これは第4講 「ビットの正体」で見た「ビットの意味は文脈が決める」 というテーマの、最も身近な具体例である。ビット列そのものを見ても、それが数値なのか文字なのかは わからない。決めているのは、そのビット列をどう解釈すると取り決めたかだけである。

最後に、ASCIIの限界にも触れておく。ASCIIは米国に偏り過ぎている。ドル記号はあるのに 英国ポンド記号はなく、多くの西欧言語で使われるアクセント付き文字もない。ギリシャ語・アラビア語・ ロシア語などの非ラテンアルファベットも、インドや東南アジアの文字も入っていない。まして中国語・ 日本語・韓国語の何万個もの表意文字を7ビットでどう扱えばよいのか。開発時にも他国の必要性は多少 考慮され、10個のコードが国別の使用のために未定義のまま残されてはいる。しかしそれで足りるはずも ない——この不足が、次の2つのセクションの主題になる。

演習 11理解

ASCIIの128個のコードは、目に見える「グラフィック文字」と、目に見えない「制御文字」に分けられる。それぞれの個数の組み合わせとして正しいものはどれか

演習 12理解

「キャリッジリターン」と「ラインフィード」という2つの制御文字は、タイプライタの動作に由来する。それぞれの働きの違いとして正しいものはどれか

演習 13理解

文章中に登場する数字(例えば年齢や個数を表す数字)をASCIIでコード化するとき、正しい扱いはどれか

演習 14理解

ASCIIの大きな限界として本文で指摘されているのはどれか

このセクション: 0 / 4 問正解

4. 文字とバイトの等価性、そしてEBCDIC

ASCIIは技術的には7ビットのコードだが、実際にはほぼ常に8ビット——1バイト——として保存される。この「1文字=1バイト」という等価性は、文字数を数えるだけでテキストが必要とするメモリ量を概算できるという、地味だが強力な利点をもたらした。一方、IBMの大型コンピュータで使われてきたEBCDICは、まったく別の出自を持つ8ビットコードである。パンチカードのゾーンパンチと数字パンチという物理的な穴の配置から出発し、長年かけて様々な技術の下で進化してきたため、アルファベットのコードが連続せず途中で途切れる。ゼロから論理的に設計されたASCIIと並べると、コード体系の設計思想の違いがはっきり見える。

ASCIIが7ビットに決まった当時、メモリは非常に高価だった。6ビットにしてシフト文字で大文字と小文字を 区別すべきだという意見もあれば、これからのコンピュータは8ビットのアーキテクチャを持つのだから 8ビットコードにすべきだという意見もあった。結果として、ASCIIは技術的には7ビットだが、 実際にはほとんど常に8ビット——1バイト——として保存されることになった。

この1文字=1バイトという等価性は、地味だが実用的な利点をもたらす。文字を数えるだけで、 そのテキストがどれくらいのメモリを必要とするかを概算できるからである。原稿の分量からファイルサイズが 見当つく、という当たり前に思える感覚は、この単純な対応関係の上に成り立っている。この関係は、 次のセクションで崩れることになる。

コンピュータの世界でASCIIが標準を支配する一方、IBMの大型コンピュータシステムの多くは別の体系を 使ってきた。拡張BCD交換用コード、すなわちEBCDICである。これは 初期の6ビットコードを拡張した8ビットコードで、その出自はIBMのパンチカードにある。

パンチカードでは、1つの列に開けられた穴の組み合わせが1文字を表す。下から10行は数字が振られていて 数字行もしくは数字パンチと呼ばれ、その上の2行は ゾーン行もしくはゾーンパンチと呼ばれる。EBCDICの8ビットコードは、 下位4ビットが数字パンチに対応するBCDコード、上位4ビットがゾーンパンチにかなり恣意的に対応する コード、という構成になっている。つまりコードの値が、紙に開ける穴の位置から決まっている。

その結果、EBCDICのアルファベットのコードは連続していない。途中に定義されていない 途切れがあり、EBCDICのテキストを扱うプログラムを書く人を悩ませてきた。これらの コードが長年にわたって様々な技術の下で進化してきたことを思えば、論理や一貫性をあまり期待できない のは無理もない。ゼロから論理的に設計されたASCIIの「連続したコード配置」がどれだけ贅沢な性質か、 並べてみるとよくわかる。

演習 15理解

ASCIIは技術的には7ビットのコードだが、実際にはほぼ常に8ビット(1バイト)として保存される。この「1文字=1バイト」という等価性の便利な点はどれか

演習 16計算

半角スペースを含む文字列「GO HOME」(G・O・空白・H・O・M・Eの7文字)をASCII(1文字1バイト)でコード化すると、何バイトになるか

演習 17理解

IBMの大型コンピュータで使われてきたEBCDICというコード体系について、正しい説明はどれか

演習 18理解

EBCDICのコード配置がASCIIほど整然としていない理由として、本文で説明されているのはどれか

このセクション: 0 / 4 問正解

5. Unicodeへの拡張 — 65,536文字への飛躍

中国語・日本語・韓国語のように何万もの文字を持つ言語は、256個の枠にはとても収まらない。シフトJISなどのダブルバイト文字セットは、特定範囲のコードを2バイト文字の第1バイトとして扱うことでこれを乗り切ったが、互換性のない標準が並立するという別の問題を生んだ。1988年、複数の大手コンピュータ企業がASCIIに代わる体系としてUnicodeの開発を始める。書籍が記述する初期のUnicodeは16ビットの固定長コードで、65,536個の文字を表現できた。最初の128個をASCIIと一致させるなど既存の標準を土台にした設計だったが、その代償として「テキストの1文字=ストレージの1バイト」という等価性は崩れる。ここでは、この初期仕様が現在のUnicodeとどう違うのかも合わせて確認する。

多くのコンピュータが文字を8ビット値として保存するなら、128個ではなく256個の文字を扱う 拡張ASCII文字コードセットを作れる。00hから7FhまではASCIIと同じに定義しておき、 80hからFFhまでを独自に定義してアクセント付き文字や非ラテンアルファベットを収容する——実際、この 方法で多くの拡張が作られた。しかし拡張が乱立した結果、混乱と非互換性も生まれてしまった。

より根本的な拡張が必要だったのは、中国語・日本語・韓国語の表意文字である。シフトJISと呼ばれる コードは、特定範囲のコードを単独の1バイト文字ではなく、2バイト文字コードの第1バイト として扱うことで、数千個の追加の文字を表現できるようにした。こうした方式は ダブルバイト文字セット、略してDBCSと呼ばれる。ただしこの方法を採る標準は1つでは なく、互換性のない複数の体系がアジアで並立することになった。しかも、通常のASCII文字は1バイト、 表意文字は2バイトと、文字によって長さが変わるため扱いも難しい。

世界のあらゆる言語に対応する唯一で明解な文字コード体系がほしい——この趣旨に賛同したいくつかの大手 コンピュータ企業が1988年に集まり、ASCIIに代わるUnicodeの開発を始めた。書籍が記述 する初期のUnicodeは16ビットのコードで、1文字が2バイトを必要とし、0000hからFFFFhの 範囲で65,536個の異なる文字を表現できるとされた。

Unicodeは白紙から出発したのではない。最初の128個の文字はASCIIコードとまったく同じで あり、00A0hから00FFhまでは拡張ASCIIのラテンアルファベットNo.1と同じである。他の世界的な標準も 取り込まれている。既存の体系を土台にしたまま、表現できる範囲だけを大きく広げた設計である。

ただし代償もある。Unicodeへ移ると、それまで成り立っていた テキストの1文字とストレージの1バイトの等価性が崩れる。同じ文書がASCIIの2倍の 容量を必要とすることになる。書籍はこれを、世界中のどんな文字も1つの体系で扱えるようになることと 引き換えの、ささいなコストにすぎないと位置づけて章を閉じる。

現在のUnicodeとの違いに注意したい。ここまでの「16ビット固定長・65,536文字」は、 書籍が書かれた当時の初期仕様である。Unicode 2.0が定められた1996年以降、コード空間は U+0000〜U+10FFFFまで拡張された。また、文字に割り当てられる番号であるコードポイント と、それを実際のビット列に変換する方式である符号化形式——UTF-8やUTF-16——が、 別の概念としてはっきり区別されるようになった。UTF-16は1文字を16ビットのコード単位1個または2個で 表す可変長の符号化であり、当初の「16ビット固定長」のままではない。もっとも、 1文字=1バイトという単純な等価性が崩れたという本章の教訓そのものは、今も変わらず 生きている。

演習 19理解

中国語・日本語・韓国語のような何万もの文字を持つ言語をコンピュータで扱うために、シフトJISなどの「ダブルバイト文字セット(DBCS)」で採用された方式はどれか

演習 20計算

初期のUnicode(1991年の策定時点)は16ビットの固定長コードとして設計された。16ビットのコードで表現できる文字の総数はいくつか

演習 21理解

Unicodeが「ゼロから作られたものではない」とされる根拠として、本文で挙げられているのはどれか

演習 22理解

Unicodeへの移行によって、それまで成り立っていたどのような関係が崩れたか

このセクション: 0 / 4 問正解