質問

圧縮された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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top