それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ファイルを指定バイトコピーする(テスト用に壊れたファイルを作る)

zip が正しく転送できてない実験をしてみたかった

zip ファイルをアップロードしたり、バックアップしたりしてて、「ファイルが壊れた」のを検出したりしたかった。状況を再現したいなと思ってもそう簡単に壊れたりはしないので、壊れたファイルを作る必要がああった。

壊れたファイルを作る → dd

壊れたファイルを作るには、ファイルに0バイトを書き込んで壊したり、半分にちぎったり、変なバイトを書き込む。

これをやるには cp などのコマンドでは出来ないので、 dd コマンド を使うことになる。Cやpythonruby で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が壊れて、ファイルが正しく転送できなかったとかプログラマ(わたし)がアホで、ファイルの転送時のネットワーク・エラー処理が甘く変なファイルが作っちゃったとか事件を再現してソレに対応した回復プログラムを作れる実験出来ると思った。

関連資料