2010-06-05 1 views
4

Строка поддержки crc32 PHP как input.And Для файла ниже код будет работать OFC.Как найти crc32 больших файлов?

crc32(file_get_contents("myfile.CSV")); 

Но если файл огромен (2 ГБ), он может вывести из памяти фатальную ошибку.

Итак, любой способ найти контрольную сумму огромных файлов?

ответ

0

This function в пользовательском Внесенный пояснениях к crc32() претензии Рассчитайте значение без полной загрузки файла. Если он работает правильно, он должен устранить любые проблемы с памятью.

Для файла размером более 2 ГБ он, однако, может остановиться при том же 32-битном ограничении, с которым вы сталкиваетесь прямо сейчас.

Если возможно, я бы вызвал внешний инструмент, который может вычислять контрольную сумму для файлов размером с один под рукой.

+0

Вы знаете какой-либо внешний инструмент, который будет вычислять crc32? Я нахожусь в Linux (Debian Flavor.) – Arshdeep

+3

Исходный код для этого здесь: http://www.csbruce.com/~csbruce/software/crc32.c – zaf

+3

@zaf - Работал удивительно. Вы - ЗВЕЗДА ** – Arshdeep

5

PHP не поддерживает файлы размером более 2 ГБ (32-разрядная ограничение)

И более эффективный способ для вычисления CRC32 из файлов:

$hash = hash_file('crc32b',"myfile.CSV"); 
+0

О порядке вы редактировали, спасибо за этот приятель :) – Arshdeep

+0

отредактировано еще раз - 'crc32b' правильного алгоритм хеширования для большинства случаев. –

0

dev-null-dweller ответ ИМО - путь.

Однако, для тех, кто ищет памяти эффективным PHP4 Backport из hash_file('crc32b', $filename);, вот это решение, основанное на this PHP manual comment, с некоторыми улучшениями:

  • Теперь он дает точно такие же результаты, чем hash_file()
  • Поддерживает 32-битные & 64-разрядные архитектуры.

Предупреждение: Перфомансы уродливые. Попытка улучшить.

Примечание: Я пробовал решение, основанное на исходном коде C из комментария zaf, но я не смог достаточно быстро перенести его на PHP.

if (!function_exists('hash_file')) 
{ 
    define('CRC_BUFFER_SIZE', 8192); 

    function hash_file($algo, $filename, $rawOutput = false) 
    { 
     $mask32bit = 0xffffffff; 

     if ($algo !== 'crc32b') 
     { 
      trigger_error("Unsupported hashing algorightm '".$algo."'", E_USER_ERROR); 
      exit; 
     } 

     $fp = fopen($filename, 'rb'); 

     if ($fp === false) 
     { 
      trigger_error("Could not open file '".$filename."' for reading.", E_USER_ERROR); 
      exit; 
     } 

     static $CRC32Table, $Reflect8Table; 
     if (!isset($CRC32Table)) 
     { 
      $Polynomial = 0x04c11db7; 
      $topBit = 1 << 31; 

      for($i = 0; $i < 256; $i++) 
      { 
       $remainder = $i << 24; 
       for ($j = 0; $j < 8; $j++) 
       { 
        if ($remainder & $topBit) 
         $remainder = ($remainder << 1)^$Polynomial; 
        else 
         $remainder = $remainder << 1; 

        $remainder &= $mask32bit; 
       } 

       $CRC32Table[$i] = $remainder; 

       if (isset($Reflect8Table[$i])) 
        continue; 
       $str = str_pad(decbin($i), 8, '0', STR_PAD_LEFT); 
       $num = bindec(strrev($str)); 
       $Reflect8Table[$i] = $num; 
       $Reflect8Table[$num] = $i; 
      } 
     } 

     $remainder = 0xffffffff; 
     while (!feof($fp)) 
     { 
      $data = fread($fp, CRC_BUFFER_SIZE); 
      $len = strlen($data); 
      for ($i = 0; $i < $len; $i++) 
      { 
       $byte = $Reflect8Table[ord($data[$i])]; 
       $index = (($remainder >> 24) & 0xff)^$byte; 
       $crc = $CRC32Table[$index]; 
       $remainder = (($remainder << 8)^$crc) & $mask32bit; 
      } 
     } 

     $str = decbin($remainder); 
     $str = str_pad($str, 32, '0', STR_PAD_LEFT); 
     $remainder = bindec(strrev($str)); 
     $result = $remainder^0xffffffff; 
     return $rawOutput ? strrev(pack('V', $result)) : dechex($result); 
    } 
} 
+0

Это интересно. Я предполагаю, что должен быть способ хэш-блока по блоку, используя собственный метод crc32(). Я помню из реализации функции crc16 (давно), что crc16 (data.crc16 (data)) == 0x0000. Если есть способ угадать, какие данные будут добавлены к следующему блоку, чтобы получить crc32 последнего блока, вам хорошо идти. Другими словами, если вы можете эффективно вычислить 32-битное значение x из crc32 (block1), такое что crc32 (x) = crc32 (block1), то crc32 (block1.block2) = crc32 (x.block2). У кого-нибудь есть идея, возможно ли это? –

+0

Еще лучше, я нашел [этот пост] (http://php.net/manual/en/function.crc32.php#100060), который позволяет подумать, что вы можете придумать функцию crc32_combine(), такую ​​что crc32_combine (crc32 (block1), crc32 (block2)) = crc32 (block1.block2). К сожалению, исходный пост, о котором идет речь, ушел!Open Source Zlib имеет реализацию crc32_combine(), которую мы могли бы заглянуть, хотя. Я постараюсь разобрать это. –

 Смежные вопросы

  • Нет связанных вопросов^_^