コードとデータ
その数がどう読まれるかは、書き方だけでは決まりません。
0xFF は 255 でしょうか、それとも −1 でしょうか。符号なしの8ビットとして見れば255、2の補数の符号つきとして見れば −1 で、どちらも成り立ちます。つまり問いのほうがまだ決まっていないわけです。ここで道具が黙って片方に決めてしまうと、もう片方のつもりだった人は、外れた答えを正しい顔で受け取ることになります。だから、どちらとして読んだのかを必ず画面に書きます。
数え方の食い違いも同じ形をしています。1テラバイトのディスクをつなぐと931ギガバイトと出るのは、売る側が1000で数え、機械が1024で数えているからで、どちらも嘘ではありません。JSON の重複キーのように、気づかないうちに片方が消えるものもあります。消えたなら消えたと言い、壊れているなら何行目の何列目かまで出す ── そういう作りにしてあります。
この分野の道具(26本)
- URLエンコードASCII 128文字の早見表と変換を1枚に。日本語1文字が %XX 3つになる理由も、バイトを並べて見せます
- バーコードの線を読む13桁のうち線として描かれているのは12桁だけ。先頭の1桁は左半分6つの字形の選び方で表されます
- 法人番号の計算12桁から法人番号の13桁を出し、13桁は式に合うかを確かめます。チェックデジットは先頭に付く1〜9
- データ量1000で数える10進と1024で数える2進を同時に出すので、1TBが931GBに見える理由が分かります
- n進数2〜36進数。負の数と2の補数(0xFF は 255 か −1 か)にも答えます
- カラーコードHEX・RGB・HSL に加えて、背景と組み合わせたコントラスト比の合否まで出します
- QRコードを作る入れた文字も作った画像もどこにも送りません。版・モード・マスクなど中身も出します
- Base64日本語と絵文字に対応。戻せないときは空にせず理由を出します
- Unix時間10桁は秒、13桁はミリ秒。桁から判断して、どう読んだかも出します
- JSON整形壊れていれば何行目の何列目かを出します。黙って消える重複キーも見つけます
- トークンって何?同じ内容の日英10組を実測しました。「日本語は3倍」が本当かどうかも数えています
- UUIDを作る乱数は128ビットではなく122ビット。「一意」は保証ではなく確率だと原文にあります
- パスワード生成暗号用の乱数で作ります。「記号を必ず1つ」がもう勧められていない理由も説明します
- パスワードの強さ点数だけでなく、弱くしている原因を名前で出します。入力は送信しません
- ビット演算AND・OR・XOR・シフト。-1を符号なしで読むと4294967295になる理由も分かります
- サブネット計算CIDRとマスクとレンジをまとめて。/31は例外で、使えるアドレスが2個あります
- 統計の計算四分位数は教科書とExcelで答えが違います。どちらの流儀で計算したかを出します
- テキストの差分見た目が同じでも違う文章があります。末尾の空白・全角スペース・改行コードまで見つけます
- cron式日と曜日は AND ではなく OR です。次に動く日時も出します
- 関数電卓工学表記は指数を3の倍数に揃えるので、そのまま「キロ」「メガ」と読めます
- ハッシュ1文字変えると答えが総取っ替えになります。それでも数桁は偶然そろう理由まで説明します
- JWTの中身署名は確かめずに中身だけ開きます。alg が none のトークンは、それ自体を警告として出します
- YAMLとJSONクォートの無い no が false になる。書いた人の意図と食い違う場所
- MarkdownをHTMLにどの流儀で変換したかを明記します。改行の扱いは流儀で違います
- 正規表現止まらなくなる書き方があるので、時間を区切って試します
- 市外局番の桁数総務省の一覧582件を数えると、市外局番と市内局番の桁数を足すとどれも5桁でした。番号を入れて確かめられます
運べる形に書き換えているだけで、隠してはいない
URL やメールの本文は、もともと限られた文字しか通らない道です。日本語をそのまま置くと途中で削られるので、%E3%81%82 のように通る文字だけに書き換えて運びます。Base64 も同じ発想で、任意のデータを64種類の文字で表します。どちらも暗号ではなく、規則を知っていれば誰でも元に戻せます。
Base64 は3バイトを4文字にするので、データがおよそ3分の4に増えます。画像を HTML に埋め込むと、その分だけ転送量が増えるということです。JWT も、点で区切られた前2つは同じ書き換えなので中身は誰でも読めます。署名は「途中で書き換えられていないこと」を示すもので、隠すためのものではありません。
1キロバイトは1000か1024か、2つある
データの大きさには、1000倍ずつ上がる数え方と、1024倍ずつ上がる数え方の2つがあります。1024は2を10回かけた数で、機械の中では区切りのよい数です。どちらも「キロバイト」と呼ばれてきたので、同じ言葉が24バイト違う量を指すことになりました。
差は桁が上がるほど開きます。1000を4回かけた数と1024を4回かけた数をくらべると、1割近く違います。売り物に「1テラバイト」と書いてあるのに、つないだ機械では少なく表示されるのは、売る側が1000で数え、機械が1024で数えているからです。
紛らわしさを減らすために、1024倍のほうを「キビ」「メビ」「ギビ」と別の名前で呼ぶ決まりが1998年に作られました。ただし画面にどちらの書き方を出すかは作る人にまかされているので、数字だけを見ても、どちらの数え方かは分かりません。
時刻と識別子は、単純そうに見えて決めごとの塊
Unix 時間は1970年1月1日からの秒数です。32ビットの符号つき整数で持つと2038年1月19日にあふれます。うるう秒を数えない決まりなので、原子時計が刻んだ秒数とも食い違います。「秒を数えているだけ」に見えて、どれも人が決めた約束の上に乗っています。
UUID の v4 は乱数から作るので、中身に意味がありません。並べても時間順にならないので、データベースの索引とは相性がよくない面があります。あとから作られた v7 は、先頭に時刻を置いてこの点を直したものです。識別子はどれも同じではなく、何のために作られたかで向き不向きが分かれます。
同じに見える文字列が、同じとは限らない
正規表現の「.」は既定では改行に当たりません。同じ書き方でも、言語や設定で当たる範囲が変わります。書いたつもりの範囲と実際に当たる範囲がずれると、通したくないものが通ります。試しながら書く形にしてあるのは、頭の中の想定を外へ出して確かめるためです。
ハッシュも、同じ入力からは同じ値が出ますが、行末が CRLF か LF かが違うだけで、まったく別の値になります。2つのファイルを比べて「違う」と出たとき、中身が違うのか、行末や文字コードだけが違うのかは、値を見ただけでは分かりません。
データの形をそろえる道具にも、決めごとがある
JSON と YAML は、どちらも同じ入れ子のデータを書ける形式です。YAML は字下げで段を表すぶん読みやすい代わりに、字下げにタブを使うと読めません。版や実装によっては、ノルウェーの国名コード NO が真偽値の false として読まれることもあります(ノルウェー問題と呼ばれています)。
差分(diff)も、見た目より決めごとの多い処理です。行ごとに比べるか文字ごとに比べるかで見え方が変わり、行末の空白や改行コードを無視するかどうかでも変わります。同じ2つのファイルから、複数の「正しい差分」が出ます。どういう比べ方をしたのかを書かない差分は、そこが読み手に見えません。