圧縮された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ライブラリコードを調べます。decompress()
アップデート1:
私が見る限り、ブロックヘッダーは次のタグで識別されます。ただし、小さなbz2ファイルにはENDMARKファイルが含まれていません。(adwのおかげで、圧縮データはバイトに埋め込まれていないため、ENDMARKのビットシフト値を探す必要があることがわかりました。)
#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計算から除外する必要があります。これは、自身のCRCを同じ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:
ブロックCRC32bzlib2
は、次のアルゴリズムを使用して計算されていることがわかります。
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にある、RobWarnockによるコードから漠然と派生しています...
...したがって、私が理解している限り、標準のCRC32チェックサム計算機を使用して事前計算/検証することはできませんが、bz2lib
実装が必要です(の155〜172行目bzlib_private.h
)。