Можно ли выполнить расчет CRC-32 в сплитах?
Я использую эту тривиальную функцию для вычисления контрольной суммы CRC данного файла:
long i, j = 0;
int k = 0;
uint crc = 0xFFFFFFFF;
FileInfo file_info = new FileInfo(file);
byte[] file_buffer = new byte[32768];
FileStream file_stream = new FileStream(@file, FileMode.Open);
while ((i = file_stream.Read(file_buffer, 0, file_buffer.Count())) > 0)
{
for (j = 0; j < i; j++)
{
uint before = crc;
k = (int)((crc ^ file_buffer[j]) & 0x000000FFL);
uint after = (uint)((crc >> 8) & 0x00FFFFFFL) ^ crc32_table[k];
crc = after;
uint test = (uint)((crc << 8) & 0x00FFFFFFL) ^ crc32_table[k];
MessageBox.Show((~crc).ToString("X"));
}
}
file_stream.Close();
return ~crc;
мой вопрос таков: скажем, у меня есть большой файл, скажем, 100MB. Есть ли связь между КПР-32 начисления первых 50 МБ и последний 50МБ и КПР-32 расчет 100МБ файл?
причина, по которой я спрашиваю, в том, что у меня есть очень большие файлы (~10 ГБ плюс-минус), которые требуют некоторого времени для генерации, но пока они генерируются, большинство частей остаются статическими, однако части в середине (известная точка) и прямо в начале (заголовок, также известная часть/длина). Вычисление контрольной суммы CRC-32 файла 10GB занимает довольно много времени, поэтому мне было интересно, есть ли способ сделать это кусками?
3 ответов
Это is действительно возможно распараллелить вычисление CRC-32, но детали грязные, и мне нужно потратить около дня, чтобы придумать код.
давайте рассмотрим базовый алгоритм CRC, где нет отрицания и нет реверсирования битов.
для строки байтов, которую вы хотите вычислить CRC, назовем ее сообщением. Основная идея заключается в том, что вы рассматриваете сообщение как многочлен в GF (2), и вычислить остаток по модулю полинома CRC.
основной алгоритм CRC является аддитивным/линейным. Если у вас есть два сообщения a и b одинаковой длины, то CRC(A XOR b) = CRC(a) XOR CRC(b).
кроме того, если вы поместите сообщение с правой стороны с n нулями, новый CRC будет старым CRC times x^N mod многочлен CRC.
со всем сказанным, единственный способ решить вашу проблему-это действительно понять математику алгоритма CRC и написать свой собственный код. Вот длинное, но очень полное объяснение CRCs:http://www.ross.net/crc/download/crc_v3.txt
это уравнение является ключевым:
CRC(a XOR b) == CRC(a) XOR CRC(b)
Предположим, вы хотите вычислить CRC следующее сообщение:
"Always desire to learn something useful."
существуют функции для вычисления CRC как:
crc_join(crc_part1("Always desire to lea"),
crc_part2("rn something useful."))
если crc_part1
и crc_part2
нули pad () свои аргументы, как показано,
crc_join
это просто XOR.
crc_part1 = crc("Always desire to lea")
crc_part2 = crc("rn something useful.")
нули могут быть учтены в crc_part1
с таблицами подстановок. Ведущие нули можно игнорировать в crc_part2
.
ссылки:
- высокоскоростная параллельная архитектура для программного обеспечения CRC
Youngju. Делай, Сон Рок. Юн, Тэкю. Ким, Кван Юи. Пьюн и Син-Чонг. Парк - https://en.wikipedia.org/wiki/Cyclic_redundancy_check