【问题标题】:Calculate MD5 of file being downloaded with PHP and CURL使用 PHP 和 CURL 计算正在下载的文件的 MD5
【发布时间】:2016-04-11 15:08:09
【问题描述】:

我有一些下载大文件的 cURL 调用。 我想知道是否可以在文件仍在下载时计算哈希?

我认为进度回调函数是实现这一目标的正确位置..

function get($urlget, $filename) {

        //Init Stuff[...]                   

        $this->fp = fopen($filename, "w+");
        $ch = curl_init();       


        //[...] irrelevant curlopt stuff

        curl_setopt($ch, CURLOPT_FILE, $this->fp);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_NOPROGRESS, 0);
        curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array($this,'curl_progress_cb'));

        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        $ret = curl_exec($ch);

        if( curl_errno($ch) ){
            $ret = FALSE;
        }

        curl_close($ch);

        fclose($this->fp);        

        return $ret;
    }

    function curl_progress_cb($dltotal, $dlnow, $ultotal, $ulnow ){
        //... Calculate MD5 of file here with $this->fp

    }

【问题讨论】:

  • 如果文件还在下载,MD5怎么做完整的hash?除非文件的所有者提供 MD5 哈希,否则我看不出你怎么做。
  • MD5 的唯一要点是,如果您获取文件 from 的地方在您下载文件之前(或可能之后)向您发送了 MD5,以便您可以检查您收到的文件是否与他们传输的文件相同,即文件在传输过程中未更改。您在下载文件时计算 MD5,或者即使在您完全接收到文件时,也没有任何意义。
  • 计算 MD5 作为 curl_progress 的一部分意味着计算 MD5 不止一次。这听起来不像会节省你的时间,事实上它听起来会增加你的下载时间。如果事实上它会在收到最后一个缓冲区时生成正确的 MD5

标签: php curl md5


【解决方案1】:

可以计算部分下载文件的md5 hash,但意义不大。每个下载的字节都会彻底改变你的哈希值,这种解决方案背后的原因是什么?

如果您需要整个文件的 md5 哈希值,那么答案是否定的。您的程序必须先下载文件,然后生成哈希。

【讨论】:

  • 我必须下载大文件,下载后我必须将它们放在目录中并存储一个哈希值以供以后的完整性检查。下载后散列文件需要时间,我正在寻找解决方案以获得一些时间
  • 散列每个“块”也需要时间,而且毫无意义
【解决方案2】:

我就是这么做的:

wget-md5.php文件中,添加如下代码:

<?php
function writeCallback($resource, $data)
{
    global $handle;
    global $handle_md5_val;
    global $handle_md5_ctx;
    $len = fwrite($handle,$data);
    hash_update($handle_md5_ctx,$data);
    return $len;
}
$handle=FALSE;
$handle_md5_val=FALSE;
$handle_md5_ctx=FALSE;
function wget_with_curl_and_md5_hashing($url,$uri) 
{
    global $handle;
    global $handle_md5_val;
    global $handle_md5_ctx;
    $handle_md5_val=FALSE;
    $handle_md5_ctx=hash_init('md5');
    $handle = fopen($uri,'w');
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL,                $url);
    curl_setopt($curl, CURLOPT_BUFFERSIZE,         64000);
    curl_setopt($curl, CURLOPT_WRITEFUNCTION,      'writeCallback');
    echo "wget_with_curl_and_md5_hashing[".$url."]=downloading\n";
    curl_exec($curl);
    curl_close($curl);
    fclose($handle);
    $handle_md5_val = hash_final($handle_md5_ctx);
    $handle_md5_ctx=FALSE;
    echo "wget_with_curl_and_md5_hashing[".$url."]=downloaded,md5=".$handle_md5_val."\n";
}
wget_with_curl_and_md5_hashing("http://archlinux.polymorf.fr/core/os/x86_64/core.files.tar.gz","core.files.tar.gz");
?>

然后运行:

$ php -f wget-md5.php
wget_with_curl_and_md5_hashing[http://archlinux.polymorf.fr/core/os/x86_64/core.files.tar.gz]=downloading
wget_with_curl_and_md5_hashing[http://archlinux.polymorf.fr/core/os/x86_64/core.files.tar.gz]=downloaded,md5=5bc1ac3bc8961cfbe78077e1ebcf7cbe

$ md5sum core.files.tar.gz 
5bc1ac3bc8961cfbe78077e1ebcf7cbe  core.files.tar.gz

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 2018-01-20
    • 1970-01-01
    相关资源
    最近更新 更多