PythonでBZ2(BZIP2)CRC32を計算/検証します
質問
圧縮されたBZIP2アーカイブのCRC32チェックサムを計算/検証しようとしています。
.magic:16 = 'BZ' signature/magic number
.version:8 = 'h' for Bzip2 ('H'uffman coding)
.hundred_k_blocksize:8 = '1'..'9' block-size 100 kB-900 kB
.compressed_magic:48 = 0x314159265359 (BCD (pi))
.crc:32 = checksum for this block
...
...
.eos_magic:48 = 0x177245385090 (BCD sqrt(pi))
.crc:32 = checksum for whole stream
.padding:0..7 = align to whole byte
http://en.wikipedia.org/wiki/bzip2
したがって、CRCチェックサムがBZ2ファイルのどこにあるかを知っていますが、それらを検証するにはどうすればよいですか。どんなチャンクがあるべきか binascii.crc32()
両方のCRCを取得するには?さまざまなチャンクのCRCを計算しようとしましたが、バイトごとにバイバイトしましたが、マッチを得ることができませんでした。
ありがとうございました。 BZIP2ソースを調べます bz2
Python Libraryコード、特に何かを見つけるかもしれません decompress()
方法。
更新1:
ブロックヘッダーは、私が見る限り、次のタグによって識別されます。 しかし、小さなBZ2ファイルにはエンドマークのファイルが含まれていません。 (ありがとう adw, 、圧縮データがバイトにパッドに入れられていないため、エンドマークのビットシフト値を探す必要があることがわかりました。)
#define BLOCK_HEADER_HI 0x00003141UL
#define BLOCK_HEADER_LO 0x59265359UL
#define BLOCK_ENDMARK_HI 0x00001772UL
#define BLOCK_ENDMARK_LO 0x45385090UL
これはからです bzlib2recover.c
ソース、ブロックは、CRCチェックサムの直前に常にビット80で始まるようです。これは、CRC計算から省略する必要があります。
searching for block boundaries ...
block 1 runs from 80 to 1182
これを計算するコードを調べます。
更新2:
bzlib2recover.c
CRCの計算関数はありません。破損したファイルからCRCをコピーするだけです。ただし、Pythonのブロック計算機機能を複製して、各ブロックの開始および終了ビットをマークアウトすることができました。 bz2
圧縮ファイル。軌道に戻って、私はそれを見つけました compress.c
のいくつかの定義を指します bzlib_private.h
.
#define BZ_INITIALISE_CRC(crcVar) crcVar = 0xffffffffL;
#define BZ_FINALISE_CRC(crcVar) crcVar = ~(crcVar);
#define BZ_UPDATE_CRC(crcVar,cha) \
{ \
crcVar = (crcVar << 8) ^ \
BZ2_crc32Table[(crcVar >> 24) ^ \
((UChar)cha)]; \
}
これらの定義は、によってアクセスされます bzlib.c
同じように、 s->blockCRC
初期化され、更新されます bzlib.c
で完成しました compress.c
. 。 2000行以上のCコードがあります。これには、何が入っていて何が起こっているのかを調べて把握するのに時間がかかります。を追加しています C
質問にもタグを付けます。
ちなみに、BZIP2のCソースは次のとおりです http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
更新3:
結局のところ bzlib2
ブロックCRC32は、次のアルゴリズムを使用して計算されます。
dataIn
エンコードされるデータです。
crcVar = 0xffffffff # Init
for cha in list(dataIn):
crcVar = crcVar & 0xffffffff # Unsigned
crcVar = ((crcVar << 8) ^ (BZ2_crc32Table[(crcVar >> 24) ^ (ord(cha))]))
return hex(~crcVar & 0xffffffff)[2:-1].upper()
ここで、BZ2_CRC32TABLEが定義されています crctable.c
にとって dataIn = "justatest"
返されたCRCはです 7948C8CB
, 、そのデータでテキストファイルを圧縮したことで、BZ2ファイル内のCRC:32チェックサムは 79 48 c8 cb
これは試合です。
結論:
bzlib2 crc32は(引用しています crctable.c
)
Comp.compression FAQのセクション51で、Rob Warnockによるコードから漠然と派生した...
...したがって、私が理解する限り、標準のCRC32チェックサム計算機を使用して事前に計算/検証することはできませんが、 bz2lib
実装(155-172インチ bzlib_private.h
).
解決
以下は、使用されるCRCアルゴリズムです bzip2
, 、Pythonで書かれています:
crcVar = 0xffffffff # Init
for cha in list(dataIn):
crcVar = crcVar & 0xffffffff # Unsigned
crcVar = ((crcVar << 8) ^ (BZ2_crc32Table[(crcVar >> 24) ^ (ord(cha))]))
return hex(~crcVar & 0xffffffff)[2:-1].upper()
(Cコードの定義は、155-172の行にあります bzlib_private.h
)
BZ2_crc32Table
配列/リストはにあります crctable.c
から bzip2
ソースコード。このCRCチェックサムアルゴリズムは、引用しています。 「comp.compression FAQのセクション51にあるRob Warnockによるコードから派生したvaguelyに派生しました...」 (crctable.c
)
チェックサムは、上に計算されます 非圧縮データ.
ソースはここからダウンロードできます: http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz