Я пытаюсь вычислить / проверить контрольные суммы CRC32 для сжатых архивов bzip2.
.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
, кажется, что блоки всегда начинаются с бита 80, прямо перед контрольной суммой CRC, которая должна быть опущена при вычислении CRC как единое целое.не может 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
.
Кстати, вот источники C для bzip2 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
, после сжатия текстового файла с этими данными контрольная сумма crc: 32 внутри файла bz2 равна 79 48 c8 cb
, что соответствует.
Вывод:
bzlib2 CRC32 (цитируя crctable.c
)
Приблизительно получен из кода Роба Уорнока, в разделе 51 комп.FAQ по сжатию ...
... поэтому, насколько я понимаю, не может быть предварительно рассчитан / проверен с использованием стандартных калькуляторов контрольной суммы CRC32, а скорее требуется реализация bz2lib
(строки 155-172 вbzlib_private.h
).