无状态增量文件哈希上下文恢复。

3

简述问题

如何在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函数可以让你保存和恢复哈希上下文。 - Enrico Dias
1个回答

1

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

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

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


问题是如何恢复上下文,而不是寻找解决问题的变通方法。别误会,你的解决方案是有效的,可以使用,只是我对恢复上下文的方法感兴趣,而不是寻找不同的方法。 - George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接