【发布时间】:2017-08-19 17:56:24
【问题描述】:
我想请教您如何在 PHP 中计算大文件的 sha256。目前,我使用 Amazon Glacier 存储旧文件并使用其 API 上传存档。最初,我只使用无法达到 MB 大小图像的小文件。当我尝试上传超过 1MB 的数据时,API 响应说我给他们的校验和与他们计算的不同。
这是我上传文件的代码:
//get the sha256 using the file path
$image = //image path;
$sha256 = hash_file("sha256", $image);
$archive = $glacier->uploadArchive([
'accountId' => '',
'body' => "",
'checksum' => $sha256,
'contentSHA256' => $sha256,
'sourceFile' => $image,
'vaultName' => 'my-vault'
]);
还有错误:
AWS HTTP error: Client error: `POST https://glacier.us-west-2.amazonaws.com/vaults/70/archives` resulted in a `400 Bad Request` response:{"code":"InvalidParameterValueException","message":"Checksum mismatch: expected 9f1d4da29b6ec24abde48cb65cc32652ff589467 (truncated...)
我尝试了下面的函数来检查最终的哈希值,但是当我打印它时它似乎不是正确的哈希值:
private function getFinalHash($file)
{
$fp = fopen($file, "r");
$ctx = hash_init('sha256');
while (!feof($fp)) {
$buffer = fgets($fp, 1024);
hash_update($ctx, $buffer);
}
$hash = hash_final($ctx, true); print_r($hash);exit;
fclose($fp);
}
生成的哈希是这样的:ŸM¢›nÂJ½äŒ¶\Ã&RÿX”gíÖ'„IoA\C÷×
Amazon Glacier API 文档显示了如何计算校验和,如下所述:
对于每个 1 MB 的有效负载数据块,计算 SHA-256 哈希值。最后一块数据可以小于 1 MB。例如,如果您要上传一个 3.2 MB 的存档,则为前三个 1 MB 数据块中的每一个计算 SHA-256 哈希值,然后计算剩余 0.2 MB 数据的 SHA-256 哈希值。这些哈希值构成了树的叶节点。
我认为提供校验和的正确方法与提供校验和有关,但我不知道应该如何使用 PHP 处理大文件。我真的需要你的帮助。
【问题讨论】:
-
您的代码有一个非常根本的问题。
checksum是一个具有 1MiB 块大小的 树形哈希,而contentSHA256是一个线性哈希,但您为两者都传递了$sha256。这两个值不可能相同除非文件小于 1 MiB。 -
@Michael-sqlbot,是的,它们对于小于 1MB 的大小是相同的。他们提供了用于获取 C# 和 Java 校验和的代码,但没有用于 PHP 的示例,这就是为什么我尝试使用 getFinalHash 函数来获取确切的哈希值。
-
@Michael-sqlbot,我尝试手动添加 sha256(我对文件使用了在线哈希计算器)并留下 contentsha256 参数,因为如果不填写它将提供,现在的问题是我提供的 sha256 与亚马逊计算的 sha256 不匹配。
标签: php amazon-web-services zend-framework2 sha256 amazon-glacier