文字 → ASCII コード

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

文字 → ASCII コード

このレッスンで分かること

  • ASCII は 7 ビット (128 種) だけ
  • コンピュータは内部では 01 しか扱えません
  • ASCII の番号は適当に振られているわけではなく、規則性があります

文字 → ASCII コード とは

1 文字を受け取り、その ASCII コード (整数) を返す関数を実装します。ord() 系の組み込みでバイト値の世界に触れます。

コンピュータは内部では 01 しか扱えません。それなのに私たちが画面で A を見られるのは、文字を整数に対応させる「文字コード」という変換ルールがあるからです。ASCII (アスキー) はその中でも最も基本的な規格で、英大文字・小文字・数字・記号など 128 種類の文字に 0 から 127 までの番号を割り当てています。たとえば A65a970 という文字は 48 です。プログラムから見ると文字は単なる「小さな整数」であり、文字列はその整数の並びにすぎません。

本章では、文字 → コード の変換を 4 言語で実装します。Python には ord()JavaScript には charCodeAt()Java には charint にキャストする方法、Go には rune の整数化があります。どの言語でも考え方は同じで、「文字に対応する整数を取り出す」だけです。これを理解しておくと、文字の比較やソート、暗号化の入り口が一気に近づきます。

文字は人間にとっての記号、整数はコンピュータにとっての記号。文字コードはその橋渡しをする辞書です。

ASCII テーブルの並びの規則性

ASCII の番号は適当に振られているわけではなく、規則性があります。'0' から '9' までは 48 から 57 に連続して並び、'A' から 'Z'65 から 90'a' から 'z'97 から 122 に並びます。この並びの規則は実務で非常に役に立ちます。たとえば '5' - '0' という引き算で文字 '5' を数値 5 に変換できますし、'a' - 'A' = 32 という関係から大文字小文字変換が +32-32 のビット演算で実現できます。

Python

print(ord('A')) # 65 print(ord('Z')) # 90 print(ord('a')) # 97 print(ord('0')) # 48 print(ord('9')) # 57

JavaScript

console.log('A'.charCodeAt(0)); // 65 console.log('a'.charCodeAt(0)); // 97 console.log('0'.charCodeAt(0)); // 48

Pythonord() は 1 文字の文字列を引数にとります。2 文字以上を渡すと TypeError が出るので注意してください。JavaScriptcharCodeAt() は文字列の何文字目を見るかをインデックスで指定する点が異なります。Java では char 型を int にキャストするだけで ASCII コードが取れます。

diagram (will load when visible)

図のポイント (テキスト併記)

  • ord は ordinal (順序数) の略

ord は ordinal (順序数) の略。文字を順序つきで並べたときの番号、というニュアンスです。

文字を整数として扱うと何が嬉しいか

文字を整数として扱える意義は、文字の比較算術演算 ができるところにあります。Python でも JavaScript でも 'a' < 'b' のような比較は内部で ASCII コードの大小比較として処理されます。だからこそ文字列のソートが自然に動きますし、'A' <= c <= 'Z' のような範囲チェックで大文字判定が書けるのです。

Python

def is_upper(c): return ord('A') <= ord(c) <= ord('Z') print(is_upper('K')) # True print(is_upper('k')) # False

暗号の世界でも文字コードは主役です。シーザー暗号と呼ばれる古典的な暗号は、各文字の ASCII コードに一定の値を足すだけで実装できます。Python であれば chr(ord(c) + 3) のように 1 行で書けます。文字コードを 整数 として扱うクセをつけておくと、後で XOR 暗号ハッシュ などにつなげやすくなります。

ASCII は 7 ビット (128 種) だけ。日本語の などは ASCII の範囲外で、後の UTF-8 レッスンで詳しく扱います。

よくある間違い

1 つめは、Pythonord('AB') のように複数文字を渡してしまうケースです。ord() は 1 文字専用で、長さ 1 の文字列か 1 bytebytes を期待します。2 つめは、JavaScript'A'.charCodeAt() と引数を省くと 0 番目とみなされるので動きますが、charCodeAt(1) のようにインデックスを間違えると NaN が返ることに注意です。3 つめは JavacharString と勘違いするケースです。Javachar は 16 ビット整数なので int への暗黙変換が効きます。

JavaScript

console.log(''.charCodeAt(0)); // NaN (空文字列)

Java

char c = 'A'; int code = c; // 65 int code2 = (int) c; // 同じく 65 (キャスト明示)

やってみよう

今回の課題は、長さ 1 の文字列を受け取り、その ASCII コードを 整数 として返す関数 charToCode(s) を実装することです。引数 s には必ず 1 文字だけが渡されると仮定して構いません。Python なら ord(s)JavaScript なら s.charCodeAt(0)Java なら (int) s.charAt(0)Go なら int(s[0]) (ASCII 範囲なら) で取り出せます。大文字 A は 65小文字 a は 97数字 0 は 48 という代表値を覚えておくと検算が楽になります。

よくある質問

Q. ASCII と UTF-8 の違いは?

A. ASCII は 7 ビットで英数字と記号 128 種類を表す古い規格です。UTF-8 は ASCII 互換で、日本語や絵文字など世界中の文字を 1〜4 バイト可変長で表現します。現代の Web は UTF-8 がデファクトで、ASCII は UTF-8 のサブセットとして自然に含まれます。

Q. 日本語 1 文字は何バイトですか?

A. UTF-8 では大半の日本語が 3 バイト、絵文字や一部の漢字(𠮟など)は 4 バイトです。UTF-16 では基本 2 バイト、サロゲートペア対象だと 4 バイトです。Java の char は UTF-16 単位なのでサロゲートペアを扱う場面で codePointAt を使う必要があります。

Q. 文字コードを意識する場面は?

A. ファイル入出力、外部 API のレスポンス、DB の Collation 設定で意識します。文字化けの 9 割は「読み込み時の charset 指定漏れ」で起きるため、IO のたびに encoding を明示する習慣が大切です。Python は open(file, encoding='utf-8') が基本です。

次のレッスン

次は コード → 文字 に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 文字→コード の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 文字→コード とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 1 文字を受け取り整数で返す
  2. ASCII 範囲の文字に対応する
  3. 戻り値の型は int

入出力例

test-cases.txt

charToCode("A")65 charToCode("Z")90 charToCode("a")97 charToCode("z")122 charToCode("0")48 charToCode("9")57 charToCode(" ")32

ヒント

main.py
main.py
学習モード

メモ

文字 → ASCII コード

⌘S で保存