一种让md5_file()更快的方法?

时间:2010-05-01 14:12:10

标签: php md5 md5-file

我目前使用md5_file()来运行大约15个网址并验证其MD5哈希值。有没有办法让我更快?贯穿所有这些过程需要太长时间。

8 个答案:

答案 0 :(得分:15)

可能你现在正在顺序完成它。即获取数据1,处理数据1,获取数据2,处理数据2,......瓶颈可能是数据传输。
您可以使用curl_multi_exec()来进行并行化。 注册一个CURLOPT_WRITEFUNCTION并处理每个数据块(因为md5()只能处理一个数据块,所以很棘手)。
或检查已完成的卷曲手柄,然后处理该手柄的数据。

编辑:快速和简单的示例使用hash extension(提供增量哈希函数)和php5.3+ closure

$urls = array(
  'http://stackoverflow.com/',
  'http://sstatic.net/so/img/logo.png',
  'http://www.gravatar.com/avatar/212151980ba7123c314251b185608b1d?s=128&d=identicon&r=PG',
  'http://de.php.net/images/php.gif'
);

$data = array();
$fnWrite = function($ch, $chunk) use(&$data) {
  foreach( $data as $d ) {
    if ( $ch===$d['curlrc'] ) {
      hash_update($d['hashrc'], $chunk);
    }
  }
};

$mh = curl_multi_init();
foreach($urls as $u) {
  $current = curl_init();
  curl_setopt($current, CURLOPT_URL, $u);
  curl_setopt($current, CURLOPT_RETURNTRANSFER, 0);
  curl_setopt($current, CURLOPT_HEADER, 0);
  curl_setopt($current, CURLOPT_WRITEFUNCTION, $fnWrite);
  curl_multi_add_handle($mh, $current);
  $hash = hash_init('md5');
  $data[] = array('url'=>$u, 'curlrc'=>$current, 'hashrc'=>$hash); 
}

$active = null;
//execute the handles
do {
  $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
  if (curl_multi_select($mh) != -1) {
    do {
      $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  }
}

foreach($data as $d) {
  curl_multi_remove_handle($mh, $d['curlrc']);
  echo $d['url'], ': ', hash_final($d['hashrc'], false), "\n";
}
curl_multi_close($mh);

(虽然没有检查过结果......但这只是一个起点)

答案 1 :(得分:0)

md5算法的速度和它可以获得的速度差不多,并且获取网址的速度非常快(如果文件很大或连接速度很慢,则速度很慢)。所以不行。你无法加快速度。

答案 2 :(得分:0)

很明显,你不能用md5_file()做任何事情来加快速度,但是,你可以使用一些 micro-optimizations 或代码重新分解来获得一些速度增益但是又一次你无法加速内置函数md5_file()

答案 3 :(得分:0)

没有。由于这是内置函数,因此无法使其更快。

但如果您的代码在MD5之前下载文件,则可以更快地优化您的下载。如果您提前了解文件大小,也可以通过设置文件大小(使用ftruncate)来查看速度的小幅提升。

此外,如果文件足够小以容纳在内存中并且您已将它们保存在内存中(因为它们已被下载或正在被读取用于其他目的),那么您可以使用md5进行操作它在内存而不是md5_file,需要从磁盘再次读取。

答案 4 :(得分:0)

据推测,您在一段时间内检查相同的网址?你能检查一下URL的最后修改过的标题吗?如果正在检查的页面没有更改,则无需重新计算MD5。

您也可以异步请求页面,以便可以并行处理它们,而不是串行处理,这样可以加快速度。

答案 5 :(得分:0)

MD5算法的速度是线性的。输入越大,花费的时间就越多,所以如果文件很大,那么你可以做的就不多了。

现在,正如VolkerK已经建议的那样,问题很可能不是md5哈希,而是通过网络检索和读取文件。

答案 6 :(得分:0)

我看到了一个非常好的优化here的建议。这对于大文件很有效,其中md5_file正在读取文件,而这个函数只是比较每个文件的第二个字节。

答案 7 :(得分:0)

解释你想做什么会有所帮助。 如果您要验证具有MD5哈希值的文件:

这不是一种安全的方法,因为它容易Collision attack。您应该使用多个哈希值(可能通过拆分文件)或使用其他哈希方法。