Php 如何查找大文件的crc32?
PHP的crc32支持字符串作为输入Php 如何查找大文件的crc32?,php,checksum,crc32,Php,Checksum,Crc32,PHP的crc32支持字符串作为输入 crc32(file_get_contents("myfile.CSV")); 但若文件变大(2GB),可能会引发内存不足的致命错误 有没有办法找到大文件的校验和?PHP不支持大于2GB的文件(32位限制) 以及从文件计算crc32的更有效方法: $hash = hash_file('crc32b',"myfile.CSV" ); 在用户为crc32()提供的注释中,声明在不完全加载文件的情况下计算值。如果它工作正常,应该可以消除任何内存问题 但是,对于
crc32(file_get_contents("myfile.CSV"));
但若文件变大(2GB),可能会引发内存不足的致命错误
有没有办法找到大文件的校验和?PHP不支持大于2GB的文件(32位限制) 以及从文件计算crc32的更有效方法:
$hash = hash_file('crc32b',"myfile.CSV" );
在用户为crc32()提供的注释中,
声明在不完全加载文件的情况下计算值。如果它工作正常,应该可以消除任何内存问题
但是,对于大于2GB的文件,它可能会在您现在遇到的相同32位限制下停止
如果可能的话,我会调用一个外部工具,它可以计算与手头文件一样大的文件的校验和 开发者的答案是我的方向 但是,对于那些正在寻找
hash_文件('crc32b',$filename)的高效内存PHP4后端口的人来说代码>,这是一个基于的解决方案,有一些改进:
- 它现在给出的结果与
hash\u file()完全相同
- 它支持32位和64位体系结构
警告:性能不好。努力改进
注意:我尝试了一个基于zaf评论中的C源代码的解决方案,但是我没有足够快的成功将其移植到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);
}
}
如果(!function_存在('hash_file'))
{
定义(“CRC缓冲区大小”,8192);
函数hash_file($algo,$filename,$rawOutput=false)
{
$mask32bit=0xffffffff;
如果($algo!=“crc32b”)
{
触发器_错误(“不支持的哈希algorightm'.$algo.”,E_用户_错误);
出口
}
$fp=fopen($filename,'rb');
如果($fp==false)
{
触发错误(“无法打开文件“.$filename.”用于读取“,”E_USER_错误);
出口
}
静态$CRC32表,$Reflect8表;
如果(!isset($CRC32表格))
{
$polymonal=0x04c11db7;
$topBit=1你知道有什么外部工具可以计算crc32吗?我在Linux上(Debian风格)。@zaf-工作得很出色,你又是一个星际编辑-crc32b
是大多数情况下正确的散列算法。这很有趣。我想应该有一种方法可以使用本机crc32()逐块散列文件方法。我记得(很久以前)在实现crc16函数时,crc16(data.crc16(data))==0x0000。如果有一种方法可以猜到下一个块要预加什么数据以获得最后一个块的crc32,那么就可以开始了。换句话说,如果可以从crc32(block1)有效地计算32位值x,这样crc32(x)=crc32(block1),然后crc32(block1.block2)=crc32(x.block2)。有人知道这是否可行吗?更妙的是,我发现可以想出一个函数crc32_combine(),这样crc32_combine(crc32(block1),crc32(block2))=crc32(block1.block2).不幸的是,它所指的原始帖子已经不存在了!开源Zlib有一个crc32_combine()的实现,不过我们可以看看。我将尝试挖掘这个。