10

圧縮された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ソースとbz2Pythonライブラリコードを調べます。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.cCRC計算機能はなく、破損したファイルから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)。

4

2 に答える 2

3

bzip2以下は、 Pythonで記述されたによって使用されるCRCアルゴリズムです。

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によるコードから漠然と派生しています...」crctable.c

チェックサムは、圧縮されていないデータに対して計算されます。

ソースはここからダウンロードできます:http ://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz

于 2010-12-21T06:18:19.190 に答える
0

既存の回答に追加するために、ストリームの最後に最終チェックサムがあります(次のeos_magicチェックサム)。これは、すべての個々のハフマンブロックチェックサムのチェックサムとして機能します。ゼロに初期化されます。既存のハフマンブロックチェックサムの検証が完了するたびに更新されます。更新するには、次のようにします。

crc: u32 = # latest validated Huffman block CRC
ccrc: u32 = # current combined checksum

ccrc = (ccrc << 1) | (ccrc >> 31);
ccrc ^= crc;

ccrc最後に、圧縮ファイルから読み取った32ビットの符号なし値に対しての値を検証します。

于 2021-01-15T07:42:27.200 に答える