CRC является аддитивным в математическом смысле, поскольку хэш CRC — это просто остаток от деления без переноса всех данных (рассматриваемых как гигантское целое число), деленного на полиномиальную константу. Используя ваш пример, это похоже на такие вещи:
7 по модулю 5 = 2
6 мод 5 = 1
(7 мод 5) + (6 мод 5) = 3
(7 + 6) по модулю 5 = 3
В этой аналогии «5» — это наш многочлен CRC.
Вот пример для игры (на основе gcc):
#include <stdio.h>
#include <x86intrin.h>
int main(void)
{
unsigned int crc_a = __builtin_ia32_crc32si( 0, 5);
printf( "crc(5) = %08X\n", crc_a );
unsigned int crc_b = __builtin_ia32_crc32si( 0, 7);
printf( "crc(7) = %08X\n", crc_b );
unsigned int crc_xor = crc_a ^ crc_b;
printf( "crc(5) XOR crc(7) = %08X\n", crc_xor );
unsigned int crc_xor2 = __builtin_ia32_crc32si( 0, 5 ^ 7);
printf( "crc(5 XOR 7) = %08X\n", crc_xor2 );
return 0;
}
Результат ожидаемый:
plxc15034> gcc -mcrc32 -Wall -O3 crctest.c
plxc15034> ./a.out
crc(5) = A6679B4B
crc(7) = 1900B8CA
crc(5) XOR crc(7) = BF672381
crc(5 XOR 7) = BF672381
Поскольку этот код использует инструкцию x86 CRC32, он будет работать только на Intel i7 или новее. Встроенная функция принимает текущий хэш CRC в качестве первого параметра и новые данные для накопления в качестве второго параметра. Возвращаемое значение — это новая работающая CRC.
Начальное текущее значение CRC, равное 0, в приведенном выше коде является критическим. Используя любое другое начальное значение, CRC не является «аддитивным» в практическом смысле, потому что вы эффективно отбрасываете информацию о целом, на которое вы делите. И это именно то, что происходит в вашем примере. Функции CRC никогда не инициализируют это начальное текущее значение CRC нулем, а обычно -1. Причина в том, что начальный CRC, равный 0, позволяет любому количеству начальных 0 в данных просто провалиться без изменения текущего значения CRC, которое остается равным 0. Таким образом, инициализация CRC равным 0 математически обоснована, но для практических целей расчета хэш, это последнее, что вам нужно.
person
srking
schedule
09.08.2011
crc(A ^ B) = crc(A) ^ crc(B)
как google меня не устраивает. - person Hyperboreus   schedule 08.08.2011CRC(A || B, iv) == CRC(B, CRC(A, iv))
, гдеA
иB
— две части сообщения,||
— соответствующий оператор конкатенации, аiv
— «вектор инициализации» для вычисления CRC, например. общий0xffffffff
. Это означает, что, имея только значение CRC для сообщенияA
и сообщенияB
,CRC(A || B)
можно тривиально вычислить без необходимости обращаться к фактическому сообщениюA
. - person JimmyB   schedule 04.06.2012