長さが合っているのに、中身が壊れていた
作った画像を、ブラウザ越しにCMSへ上げる必要がありました。一度に送れない大きさだったので、分割して送り、向こう側でつなぎ直しています。
つなぎ直した長さは、元のデータと1文字も違いませんでした。それでも上がった画像は真っ黒でした。
長さが合っているのに中身が壊れていた原因と、それを見つけるまでに遠回りしたこと。そして分割して送るときに、検証をどこに置くべきかです。
長さが合うことは、無事の証明にならない
最初に確認したのは長さでした。送った文字数と受け取った文字数が一致していたので、無事に届いたと判断しました。
これが間違いです。どこかで1文字増えて、どこかで1文字減れば、長さは変わりません。実際に起きていたのはこれでした。
確かめたかったのは「中身が同じか」です。確かめたのは「長さが同じか」でした。長さは数えるだけで済むので、つい代わりに使ってしまいました。
長さが違えば壊れていると分かりますが、長さが同じでも壊れていないとは言えません。片方向にしか使えない検査を、両方向に使っていました。
どこで壊れたのかが分からない
次に困ったのが、壊れた場所の特定です。
全体をひとつの塊として扱っていたので、「どこかが壊れている」以上のことが分かりません。やり直すとしたら全体をやり直すしかなく、しかも同じ場所でまた壊れるかどうかは運任せになります。
実際、一度送り直しても同じように壊れました。何が起きているか分からないまま、同じ操作を繰り返していました。
分割して送るなら、検証も分割する
やり方を変えました。送る側で分割したときに、各かたまりごとに短い検査値を計算して一緒に渡します。受け取る側は、つなぐ前にその場で照合します。
| 全体だけを検証 | かたまりごとに検証 | |
|---|---|---|
| 壊れたことに気づける | すべて送り終えたあと | そのかたまりを受け取った時点 |
| 壊れた場所 | 分からない | そのかたまりだと確定する |
| やり直す範囲 | 全体 | そのかたまりだけ |
これに変えた途端、壊れている場所が一発で出ました。しかも受け取り側が拒否を返すので、壊れたまま先へ進むことがなくなります。
検証を全体にしか置かないと、失敗も全体になります。細かく検証すれば、失敗も細かくなります。
分割する目的は「一度に送れないから」でしたが、分割したことの利点は、失敗を小さくできることのほうにありました。
検証は、転送の「あと」ではなく「一部」にする
ここが今回の考え方の変化でした。
最初は、送り終えてから確かめる、という順番で組んでいました。転送と検証が別の工程になっていて、間に「壊れたまま進む余地」があります。
いまは、検査値が合わないかたまりは受け取らない形にしています。検証は転送の後工程ではなく、転送の一部です。こうすると「受け取れた」と「正しい」が同じ意味になります。
形式として正しくても、中身が正しいとは限らない
もうひとつ、別の層の話があります。
検査値が合って、データが完全に届いた。そこまで確認しても、上がった画像が意図したものかは、まだ分かりません。実際、最初に壊れた画像は「画像ファイルとしては正しい形式」で、開くこともできました。中身が真っ黒だっただけです。
そこで、送り先に登録する前に、実際に画素を読むようにしました。画面には出さず、いくつかの座標の色を取って、想定した配色になっているかを見ます。真っ黒なら、そこで止まります。
「形式として妥当か」と「意味として正しいか」は別の検査です。前者は自動で分かりますが、後者は中身を見に行かないと分かりません。
面倒に見えますが、やっているのは数点の色を読むだけです。壊れたものを世に出してから気づくコストと比べれば、はるかに安く済みます。
今回の学び
まず、長さの一致は、内容の一致ではないこと。確かめやすい指標を、確かめたい事実の代わりに使うと、一致しているのに壊れている状態を見逃します。
次に、失敗の大きさは、検証をどの粒度に置いたかで決まること。全体にしか検証を置かなければ、やり直しも全体になり、原因も特定できません。分けて送るなら、分けて確かめるべきでした。
そして、検証は工程の後ろに置くと、壊れたまま進む余地が残ること。転送の一部にしてしまえば、受け取れたことがそのまま正しさの証明になります。順番を変えただけで、確認という作業そのものが要らなくなりました。
最後に、形式の正しさと意味の正しさは、別々に確かめる必要があること。壊れた画像は画像として開けました。開けることと、意図したものであることは、まったく別の話でした。
この記事を共有する
関連記事

細かく刻んでも直らなかった、経路を変えたら一度で通った
記事のアイキャッチ画像を、CMSへ入れる作業をしていました。画像を文字列に変換して、少しずつ送り込む方法です。 ところが、ときどき壊れます。送った文字列と、届いた文字列が違う。 対処として分割をどんどん細かくしていきまし […]
自分のブログに記事が投稿できない — WAFの誤検知と、渡し方を変える解決
自分のブログに、自分で書いた記事が投稿できなくなりました。 原因はサーバーのWAF(Webアプリケーションファイアウォール)でした。記事の本文に含まれるコードが、攻撃と誤検知されて遮断されていたのです。回避を4種類試して […]

順番で決まる名前は、いつか壊れる
用語集の102語に記事からリンクを張ろうとしたら、そのIDが「何番目に出てきたか」で決まっていた。1語足すたびに以降が全部ずれる仕組みを、手書きの対応表に置き換えた話。