Base62 のエンコードとデコードの方法
- 入力 · テキストにテキストを入力するか貼り付けます。Base62 の文字列が出力 · Base62 に表示されます。
- 出力の下のアルファベットを、やり取りするシステムに合わせて 0-9 A-Z a-z か 0-9 a-z A-Z にします。
- 数値の ID なら、変換元を整数(多倍長)にして 10進数で入力します。生のバイト列なら Hex(16進数)か Base64 を選びます。
- デコードするには、方向の切り替えで Base62 → テキストをクリックします。このときアルファベットの選択は入力の下に移り、エンコードに使ったものと同じでなければなりません。
結果が異なる 2 種類の並び
Base62 には RFC がなく、62 文字の並び方は世の中に 2 通りあります。この変換ツールはどちらにも対応しています。
| アルファベット | A の値 | a の値 | Hello | 数値の 1000000 |
|---|---|---|---|---|
0-9 A-Z a-z | 10 | 36 | 5TP3P3v | 4C92 |
0-9 a-z A-Z | 36 | 10 | 5tp3p3V | 4c92 |
1 つ目の並びは ASCII の順に従うので、同じ長さのエンコード済み文字列は、数と同じ順に並びます。GMP は基数 37〜62 でこの並びを使います。2 つ目の並びは、16進数の小文字 a-f を延長した場合と一致し、「反転」アルファベットと呼ぶライブラリもあります。
一方の出力は、もう一方のすべての英字の大文字と小文字を入れ替えたものです。そのため間違いに気づきにくくなっています。5tp3p3V を間違った並びでデコードしても成功しますが、Hello ではなくバイト列 4e 08 14 29 1d が返ってきます。デコードした値が意味不明に見えたら、データを疑う前にもう一方の並びを試してください。
短い ID と URL のための Base62
短縮 URL や ID の仕組みで Base62 が使われるのは、どの文字も URL のパス、ファイル名、ダブルクリックでの選択で安全で、結果が短いからです。データベースの ID は数なので、整数(多倍長)からエンコードします。
| 10進数 | Base62(0-9A-Za-z) |
|---|---|
125 | 21 |
3843 | zz |
3844 | 100 |
1000000 | 4C92 |
123456789 | 8M0kX |
7 文字で 62^7 − 1、約 3.5 兆までの数を表せます。ランダムな ID なら、ランダムなバイト列をエンコードします。16 バイトの UUID は、16進数の 32 文字に対して 21〜22 文字になります。
短い連番の ID は、レコードがいくつあるかを明かしてしまい、推測も容易です。それが問題になるなら、カウンターではなくランダムなバイト列をエンコードしてください。
Base62 でのバイト列と先頭のゼロの扱い
62 は 2 のべき乗ではないため、Base62 はビットのグループを文字に対応させることができません。入力をビッグエンディアンの 1 つの数として読み、その数を 62 進数に変換します。このままでは先頭のゼロバイトが消えてしまうので、このツールはそれぞれについて 0 の桁を 1 つ書きます。バイト列 00 00 は 00 に、00 ff は 047 にエンコードされます。
ここでもライブラリによって扱いが違います。多くは数だけをエンコードして先頭のゼロを落とし、固定幅の形式では代わりに決まった長さまでパディングします。受け手が固定幅を求める場合は、出力の左を 0 で埋めてください。大きな数として扱う方式は、入力の長さの 2 乗で増えるコストもかかるため、このツールは Base62 の入力を 64 KB までに制限しています。
Python での Base62
Python の標準ライブラリには Base62 がありません。整数の ID なら、変換は数行で書けます。
ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
def b62encode(n: int) -> str:
if n == 0:
return ALPHABET[0]
out = ""
while n:
n, r = divmod(n, 62)
out = ALPHABET[r] + out
return out
def b62decode(s: str) -> int:
n = 0
for ch in s:
n = n * 62 + ALPHABET.index(ch)
return n
b62encode(1000000) # '4C92'
b62decode("8M0kX") # 123456789
もう一方の並びにするには、ALPHABET の 2 つの英字ブロックを入れ替えます。バイト列の場合は、先に int.from_bytes(data, "big") で変換してください。バイト列の扱いについて詳しくは Python をご覧ください。
よくある質問
Base62 のアルファベットとは何ですか?
10 個の数字と、26 個の大文字、26 個の小文字の英字です。合計 62 文字で、それ以外は含みません。数字が最初に来るのは共通ですが、次に大文字が来るか(0-9A-Za-z)小文字が来るか(0-9a-zA-Z)はライブラリによって異なります。
Base62 と Base64 の違いは何ですか?
Base64 は + と /(または - と _)、= のパディングを加え、固定の 6 ビットのグループを対応させます。Base62 は英字と数字だけを使うのでどこでもエスケープが不要ですが、62 は 2 のべき乗ではないため、データを 1 つの大きな数として扱う必要があります。出力は Base64 より約 1% 長くなります。
数値を Base62 にエンコードするには?
変換元を整数(多倍長)にして、10進数の数を入力します。デフォルトのアルファベットでは 1000000 が 4C92 になります。数をテキストとしてエンコードすると、数字の文字そのものがエンコードされてしまいます。
Base62 は大文字と小文字を区別しますか?
区別します。A と a は別の桁で、デフォルトの並びではそれぞれ 10 と 36 です。URL や ID を小文字にしてしまうシステムは Base62 の文字列を壊します。大文字小文字が失われる可能性があるなら Base36 を使ってください。