zip が正しく転送できてない実験をしてみたかった
zip ファイルをアップロードしたり、バックアップしたりしてて、「ファイルが壊れた」のを検出したりしたかった。状況を再現したいなと思ってもそう簡単に壊れたりはしないので、壊れたファイルを作る必要がああった。
壊れたファイルを作る → dd
壊れたファイルを作るには、ファイルに0バイトを書き込んで壊したり、半分にちぎったり、変なバイトを書き込む。
これをやるには cp などのコマンドでは出来ないので、 dd コマンド
を使うことになる。Cやpythonやruby でfopenして書いても良いんだけど、dd コマンドが一番楽だと思う。
dd でファイルをコピーする。
最初に dd でファイルをコピーして、使い方を確認しておく
takuya@Desktop$ dd if=test.zip of=test.safe.zip 0+1 records in 0+1 records out 438 bytes copied, 0.000324 s, 1.4 MB/s takuya@Desktop$ md5sum test*.zip 48949110457174e7f10541080235174b test.safe.zip 48949110457174e7f10541080235174b test.zip
壊れたzip にする。( コピーを途中で中断した
先頭から400バイトを読み込んで、残りをコピーぜずに、中断された状況を作ってみる。
takuya@Desktop$ dd if=test.zip of=test.corrupted.zip bs=1 count=400 400+0 records in 400+0 records out 400 bytes copied, 0.00151 s, 265 kB/s
結果を確認
takuya@Desktop$ md5sum test*.zip 7eeef77e910c3a770c557e3bb9d3d8a1 test.corrupted.zip 48949110457174e7f10541080235174b test.zip
壊れたことを確認する。 unzip しようとしても、return code = 9 が帰ってきて、異常終了したことが分かる。
takuya@Desktop$ unzip -t test.corrupted.zip ; echo $? Archive: test.corrupted.zip End-of-central-directory signature not found. Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive. unzip: cannot find zipfile directory in one of test.corrupted.zip or test.corrupted.zip.zip, and cannot find test.corrupted.zip.ZIP, period. 9
ただしこの状態でも zip のエントリ一覧は取れたりする・・・だから壊れたことを再現できるよね。
takuya@Desktop$ lsar test.corrupted.zip ; echo $? test.corrupted.zip: Zip tet/ tet/a tet/b 0
変なバイトを書いてしまった
最初に、変なバイトを書き込むファイルを用意する。
takuya@Desktop$ cp test.zip test.wrong-byte.zip
400 バイト目から、30バイトのZEROを書き込んで壊す。
takuya@Desktop$ dd if=/dev/zero of=test.wrong-byte.zip bs=1 skip=400 count=30 30+0 records in 30+0 records out 30 bytes copied, 0.000153 s, 196 kB/s
ファイルが壊れたことを確認してみる
takuya@Desktop$ unzip test.wrong-byte.zip -t Archive: test.wrong-byte.zip End-of-central-directory signature not found. Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive. unzip: cannot find zipfile directory in one of test.wrong-byte.zip or test.wrong-byte.zip.zip, and cannot find test.wrong-byte.zip.ZIP, period.
これで、ファイルが壊れたりHDDが壊れて、ファイルが正しく転送できなかったとかプログラマ(わたし)がアホで、ファイルの転送時のネットワーク・エラー処理が甘く変なファイルが作っちゃったとか事件を再現してソレに対応した回復プログラムを作れる実験出来ると思った。