全プロセスの詳細解説
-
49文字のASCII JSONペイロードから68文字への変換と復元 5 ステップ
入力は
eyJuYW1lIjoiU3BvY2siLCJyb2xlIjoic2NpZW50aXN0IiwiYWN0aXZlIjp0cnVlfQ==であり、その下のペイロードは 49 文字の ASCII JSON{"name":"Spock","role":"scientist","active":true}です。 パネルには Characters に 68、Bytes に 68 と表示されています。エンコードされた文字列を数えずに 68 を 49 から導き出し、さらにそこから元に戻してください。-
Base64 は基数の変更であり、暗号ではありません。64 = 26 であるため、出力の各文字は 6 ビットを保持します。入力の 3 バイトは 24 ビットを保持し、6 は 24 を割り切ることができます。フォーマットの全容はこれだけであり、3 バイトの入力に対して 4 文字が出力され、余りは出ません。
-
49 バイトは 16 個の完全なトリプルと余り 1 バイトからなります。トリプルの部分は単純で、16 × 4 = 64 文字となり、その一文字一文字が満額の 6 ビットを担います。
-
端数のバイトがあるからこそパディングが発生します。8 ビットは 6 の倍数ではないため、4 ビットのゼロが補われて 12 ビット(2 文字分)となり、2 つの '=' 記号がカルテットを完成させます。64 + 2 + 2 = 68 となります。各 '=' は、独自のビットを持たなかった文字位置を示しています。
-
パネルのどちらの行も 68 と読み取れますが、その一致はこの文字列について何も物語っていません。Base64 のアルファベットは ASCII であるため、出力されるすべての文字は正確に 1 バイトです。どのような Base64 入力であっても、Bytes 行は Characters 行に追従します。
-
今度は逆に計算します。68 ÷ 4 = 17 カルテット、17 × 3 = 51 バイトのスロットから、パディングが空であると認める 2 スロットを差し引くと 49 です。単一のバイトすらデコードすることなく、ペイロードのサイズが復元されました。
解答
68 文字で 49 バイトであり、'=' 記号のおかげでラッパーから 49 を直接読み戻すことができます。 逆の計算ができることこそが役に立つ半分です。Base64 文字列の長さはペイロードの長さにのみ依存し、他には何も依存しないため、閲覧を許可されていないものの正確なサイズを特定できます。これは、このページのどの検出器がコンテンツについて行う言及よりも強い主張です。もう半分は代償です。4 文字につき 3 バイトという効率は決して改善しないため、極限において Base64 のコストは 4/3 になります。1 MiB のファイルは 1,398,104 文字として届き、純粋な包装だけで 341 KiB になります。この文字列は 68/49 = 1.388 とさらに効率が悪くなります。2 文字のパディングが固定の割増金であり、49 バイトではそれを薄めるには短すぎるからです。
-
-
GUID/UUID v4のランダムビットと重複までに生成される識別子 6 ステップ
入力は
550e8400-e29b-41d4-a716-446655440000であり、パネルでは GUID/UUID v4 と表記されると同時に Base64URL としてデコードする機能も提供されています。 実際にはいくつのビットがランダムに選択されたのか、そして重複が発生する可能性が低くなくなるまでに、このような識別子をいくつ発行できるかを計算してください。-
まずその形状を数えます。8-4-4-4-12 の十六進桁で、グループの間に 4 つのハイフンがあるため、32 + 4 = 36 文字となり、十六進桁とハイフンはすべて ASCII なので Bytes 行も 36 で一致します。それら 4 つのハイフンが何に値するか注意してください。固定位置にあるため、それらは 0 ビットを担います。
-
十六進の各桁は 4 ビットなので、対象となる 32 桁は 128 ビットを保持します。これが UUID について通常引用される数値ですが、この文字列に関しては高すぎます。
-
13 番目の桁と 17 番目の桁がその理由です。13 番目の桁は 4 であり、これはバージョンフィールドです。バージョン 4 の UUID はそこに 4 を置くことが義務付けられているため、それら 4 ビットが選択肢となることはありませんでした。17 番目の桁は 'a' で、2 進数では 1010 であり、その先頭 2 ビットはバリアントタグとして 10 に固定されています。フォーマットの指定に費やされた 6 ビットを差し引くと、122 ビットが残ります。
-
したがって、空間の大きさは 2122、およそ 5.32 × 1036 であり、128 ビットが与えたであろう 3.40 × 1038 には達しません。
-
重複は空間の大きさではなく、誕生日の法則に従います。n 個の識別子をランダムに抽出するとき、あるペアが一致する確率は n2/(2N) のように増加し、これを 0.5 に設定すると n = 1.177√N が得られます。カウントは平方根に伴って変化するため、6 ビットの損失(ステップ 3 で生じたもの)が 8 倍の係数となり、64 倍にはならない理由がここにあります。
-
√N は 2.31 × 1018 であるため、n は 2.7 × 1018 となります。
解答
122 ビットであり、2.7 × 1018 個の UUID で重複の確率が 0.5 に達します。 毎秒 109 個のペースで発行した場合、それは 86 年に相当します。そしてこれこそが、レジストリも調整もなしに各マシンに固有のものを生成させる根拠のすべてです。プロトコルではなく、単に到達不能なほど大きな数値なのです。これを最初の問題と並べると、その対比こそがこのページの目的です。Base64 は各文字に 6 ビットを詰め込みますが、この文字列は 36 文字を費やして 122 ビットを表しており、1 文字あたり 3.4 ビットとなります。そのため、同じ識別子は 21 文字の base64url に収まります。残りの 15 文字が買っているのは可読性であり、情報ではありません。そして、パネルが提供する Base64URL デコードがテキストではなくバイナリとしてフラグが立てられて返されるのは、極めて明白な理由からです。そこには見つけ出すべきエンコードされた内容など最初から存在しなかったのです。
-
参考文献 (1)
- The alphabets and padding rules the detector reasons about, normatively: S. Josefsson, "The Base16, Base32, and Base64 Data Encodings." RFC 4648, IETF, 2006.