Вычислить / проверить bz2 (bzip2) CRC32 в Python
Я пытаюсь вычислить / проверить контрольные суммы 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 часто задаваемых вопросов о comp.compression...
... таким образом, насколько я понимаю, не может быть предварительно рассчитан / проверен с использованием стандартных калькуляторов контрольной суммы CRC32, а скорее требует bz2lib
реализация (строки 155-172 в bzlib_private.h
).
3 ответа
Ниже приводится алгоритм 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 цитируется следующим образом: "... смутно получен из кода Роба Уорнока в Разделе 51 FAQ по comp.compression..." (crctable.c
)
Контрольные суммы рассчитываются по несжатым данным.
Источники можно скачать здесь: http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
Проверьте библиотеку python fastcrc, в которой реализована реализация bzip2 crc32.
https://fastcrc.readthedocs.io/en/latest/#fastcrc.crc32.bzip2
Чтобы добавить к существующему ответу, в конце потока есть окончательная контрольная сумма (тот, что после
crc: u32 = # latest validated Huffman block CRC
ccrc: u32 = # current combined checksum
ccrc = (ccrc << 1) | (ccrc >> 31);
ccrc ^= crc;
В конце подтвердите значение