【问题标题】:Reading large portions of files for hashing/checksums读取大部分文件以进行散列/校验和
【发布时间】:2015-10-20 23:39:15
【问题描述】:

如果我有三个get参数:

$filename = $_GET['filename'];
$start    = $_GET['start'];
$size     = $_GET['size'];

我正在读取文件的一部分,如下所示:

$handle   = fopen($basepath . $filename, "rb");
fseek($handle, $start);
$contents = fread($handle, $size);
echo md5($contents);

如何读取文件的大部分内容(从 1mb 到 1gb)并创建其内容的哈希或校验和,而无需为整个读取分配足够的内存?

目前,如果我尝试对文件的太大部分进行哈希处理,则会出现内存错误,因为 php 无法分配足够的内存(大约 400mb)。

是否有一个哈希函数,我可以一次消化部分文件而不是一次消化整个内容(例如,从$start 开始读取 100kb 块并将其提供给函数,直到 @987654324 @被满足)?我将如何分块读取文件,以便从$start 开始并读取$size 字节?

如果没有这样的散列或校验和函数支持一次提供数据块,file_get_contents() 会解决为大量读取分配内存的问题吗?我不完全确定该功能是如何工作的。

谢谢。

【问题讨论】:

  • 只为文件的一部分获取哈希的目的是什么?
  • 它是下载器脚本的一部分,客户端可以在其中分部分下载 http 文件,并要求服务器端比较该文件部分的哈希/校验和。
  • 为什么不用 zip 或 tar 分割服务器端
  • 我不想在服务器端预先拆分文件或以任何方式修改它们,因此为什么我使用范围标头告诉 httpd 我请求的文件的哪个段下载。除非我可以让 php 自动执行此拆分并将文件的正确部分提供给客户端脚本,然后再将其直接删除,尽管我真的不希望将新文件写入文件系统。

标签: php hash md5 fread


【解决方案1】:

http://php.net/manual/en/function.hash-update.php

<?php
define('CHUNK', 65536);

//$file = 'alargefile.img';
//$start = 256 * 1024 * 1024;
//$size = 512 * 1024 * 1024;

$fp = fopen($file, "r");
fseek($fp, $start);
$ctx = hash_init('md5');
while ($size > 0) {
  $buffer = fread($fp, min($size, CHUNK));
  hash_update($ctx, $buffer);
  $size -= CHUNK;
}
$hash = hash_final($ctx);
fclose($fp);
print $hash;
?>

【讨论】:

  • 这正是我一直在寻找的内容,尽管我相信您阅读文件的方式存在错误。逐个减少$size 变量会连续多次产生相同的哈希值。与md5sum 相比,将$start 设置为0 并将$size 设置为文件大小会产生错误的md5 哈希值。有什么想法吗?
  • 已修复。问题是fgets,大概它停在换行符上。将其更改为 fread 解决了问题,并且它可以正常工作。谢谢~
猜你喜欢
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
  • 2023-04-03
  • 2012-05-26
  • 1970-01-01
相关资源
最近更新 更多