【问题标题】:Stateless incremental file hashing context resume无状态增量文件哈希上下文恢复
【发布时间】:2013-07-21 08:37:15
【问题描述】:

简短的问题

如何在 PHP 中“恢复 hash_context”?


背景与现状

该软件的目标是逐块(同步)接收大文件,计算该文件的 MD5 和 SHA1 并生成(完整文件的)下载链接。类似于 rapidshare 的东西,但不是完全发送文件,而是逐块发送文件。

目前该软件正在使用此逻辑:
它在每个文件会话中同步接收文件块(一个大文件的 10MB 块)。收到所有块后,我需要计算文件的 MD5 和 SHA1,这对于超过 1GB 的文件需要很长时间。

文件终结器的伪代码(收到所有块时):

$fileKey = $_GET['KEY'];
$ctxMd5 = hash_init('md5');
$ctxSha1 = hash_init('sha1');

$fh = fopen('file/containing/all_chunks.tmp', 'r');
while(!feof($fh)) {
$data = fread($fh, CHUNK_SIZE);
    hash_update($ctxMd5, $data);
    hash_update($ctxSha1, $data);
}
$md5 = hash_final($ctxMd5);
$sha1= hash_final($ctxSha1);

saveFileHashes($fileKey, $md5, $sha1);

问题是当所有块都上传时,用户必须等到脚本计算两个哈希值,这非常令人沮丧。


问题的解决方案

我想以这种方式更改接收逻辑:
我想恢复或创建新的哈希上下文,而不是在接收和保存所有块时计算哈希值,增加上下文,保存散列上下文状态并保存文件块,当收到每个块时。

块接收器的伪代码:

$chunkData = getIncommingChunkData();
$fileKey = $_GET['KEY'];

$ctxMd5 = resumeMd5HasingContext($fileKey);
$ctxSha1 = resumeSha1HasingContext($fileKey);

hash_update($ctxMd5, $chunkData);
hash_update($ctxSha1, $chunkData);

saveMd5HashingContext($fileKey, $ctxMd5)
saveSha1HashingContext($fileKey, $ctxSha1)

appendFileChunk($fileKey, $chunkData);

问题

主要问题是 PHP 资源不可序列化,hash_init 也没有提供恢复上下文的方法。

我想知道如何实现上述所有目标?

【问题讨论】:

  • 我不知道如何序列化上下文以供另一个进程使用,但 hash_copyhash_update 函数可以让您保存和恢复哈希上下文。

标签: php hash md5 sha1 stateless


【解决方案1】:

解决问题的一个想法:也许您应该将接收过程与连接/散列过程分开。

当您初始化传输时,您的脚本可以启动一个在后台运行的持久脚本,等待块,计算每个可用块的哈希值,将它们附加到文件并在收到所有块时退出,全部在一次执行中。

您的接收脚本只需将上传的块文件移动到一个临时目录,以使它们可用于持久进程。

【讨论】:

  • 问题是如何恢复上下文,而不是找到解决问题的方法。不要误会我的意思,您的解决方案是有效的并且可以使用,只是我对一种恢复上下文而不是找到不同方法的方法感兴趣。
猜你喜欢
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多