У нас есть очень старая, неподдерживаемая программа, которая копирует файлы через общие ресурсы SMB. У этого есть алгоритм контрольной суммы, чтобы определить, изменилось ли содержимое файла перед копированием. Алгоритм кажется легко обманутым - мы только что нашли пример, когда два файла, идентичные, за исключением одного «1», меняющегося на «2», возвращают ту же контрольную сумму. Вот алгоритм:Можно ли улучшить алгоритм контрольной суммы?
unsigned long GetFileCheckSum(CString PathFilename)
{
FILE* File;
unsigned long CheckSum = 0;
unsigned long Data = 0;
unsigned long Count = 0;
if ((File = fopen(PathFilename, "rb")) != NULL)
{
while (fread(&Data, 1, sizeof(unsigned long), File) != FALSE)
{
CheckSum ^= Data + ++Count;
Data = 0;
}
fclose(File);
}
return CheckSum;
}
Я не так много программиста (я сисадмин), но я знаю, исключающее на основе контрольной суммы будет довольно сырой. Какова вероятность того, что этот алгоритм вернет ту же контрольную сумму для двух файлов одного размера с другим содержимым? (Я не ожидаю точного ответа, «удаленный» или «вполне вероятный» в порядке.)
Как его можно улучшить без огромного удара производительности?
И наконец, что происходит с fread()
? Я быстро просмотрел документацию, но я не мог понять. Устанавливается ли Data
каждому байту файла? Редактировать: хорошо, поэтому он читает файл в unsigned long
(предположим, что здесь 32-битная ОС) куски. Что содержит каждый кусок? Если содержимое файла abcd
, то каково значение Data
на первом проходе? Является ли это (в Perl):
(ord('a') << 24) & (ord('b') << 16) & (ord('c') << 8) & ord('d')
fread читает один элемент по адресу Data. Размер считываемого элемента - это размер unsigned long (по-моему, 8 байтов). –
Размер unsigned long зависит от типа архитектуры процессора (32/64 бит), поэтому используется sizeof. – schnaader
Исправьте пример Perl. –