Я пытаюсь вычислить / проверить контрольные суммы 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 по comp.compression ...
... таким образом, насколько я понимаю, невозможно предварительно вычислить / проверить с помощью стандартных калькуляторов контрольной суммы CRC32, а скорее требует реализации bz2lib
(строки 155-172 в bzlib_private.h
).
bzip2
использует 32-битный стандарт CRC AUTODIN-II, Ethernet и FDDI - person soulseekah   schedule 17.12.2010hello
в текстовом файле. Я пробовал разные онлайн-калькуляторы CRC32 и библиотечные, которые у меня есть. Либо мне очень не везет, либо я что-то не так делаю. - person soulseekah   schedule 17.12.2010open("test.txt.bz2","wb").write(bz2.compress("hello"))
CRC32 указывает, что CRC32 для блока19 31 65 3d
, тогда какhex(crc32("hello"))
(изbinascii
) возвращает36 10 a6 86
- person soulseekah   schedule 17.12.2010