10

我目前使用md5_file()运行大约 15 个 URL 并验证它们的 MD5 哈希值。有没有办法让我更快?遍历所有这些需要很长时间。

4

8 回答 8

15

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

编辑:使用散列扩展(提供增量散列函数)和php5.3+ 闭包的 quick&dirty 示例:

$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);

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

于 2010-05-01T14:24:21.370 回答
0

我在这里看到了一个非常好的优化建议。这尤其适用于大文件,其中 md5_file 正在读取文件,并且此函数只是比较每个文件的第二个字节。

于 2010-09-21T11:53:56.293 回答
0

md5 算法的速度非常快,并且获取 url 的速度也非常快(如果文件很大或者连接速度很慢,则速度很慢)。所以不行。你不能让它更快。

于 2010-05-01T14:14:20.997 回答
0

很明显,你不能做任何事情md5_file()来提高速度,但是,你可以使用一些微优化或代码重构来获得一些速度增益,但同样你不能加快内置函数的速度md5_file()

于 2010-05-01T14:14:31.823 回答
0

不,因为这是一个内置功能,所以没有办法让它更快。

但是,如果您的代码在对文件进行 MD5 处理之前下载文件,则可以优化您的下载速度以加快速度。如果您提前知道文件的大小,您还可以通过在写入文件之前设置文件的大小(使用 ftruncate)来看到速度的小幅提升。

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

于 2010-05-01T14:17:30.533 回答
0

大概您在一段时间内检查相同的 URL?你能检查一下最后修改的 URL 标头吗?如果被检查的页面没有改变,则不需要重新计算 MD5。

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

于 2010-05-01T14:36:54.643 回答
0

MD5算法的速度是线性的。输入越大,花费的时间就越多,所以如果文件很大,你真的无能为力。

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

于 2010-05-01T14:38:15.707 回答
-1

解释你想做什么会有所帮助。如果您想使用其 MD5 哈希验证文件:

这不是一种安全的方法,因为它容易受到碰撞攻击。您应该使用多个散列(可能通过拆分文件)或使用其他散列方法。

于 2017-08-29T11:46:36.233 回答