我想用 PHP 计算大文件的 SHA256。目前,我正在使用 Amazon Glacier 来存储旧文件及其 API 来上传存档。最初,我只是使用无法达到 MB 大小图像的小文件。当我尝试上传超过 1MB 的文件时,API 响应说我给他们的校验和与他们计算的不同。
\n\n这是我上传文件的代码:
\n\n//get the sha256 using the file path\n$image = //image path;\n$sha256 = hash_file("sha256", $image);\n\n$archive = $glacier->uploadArchive([\n \'accountId\' => \'\', \n \'body\' => "",\n \'checksum\' => $sha256,\n \'contentSHA256\' => $sha256,\n \'sourceFile\' => $image,\n \'vaultName\' => \'my-vault\'\n ]);\nRun Code Online (Sandbox Code Playgroud)\n\n和错误:
\n\nAWS 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...)\n
我尝试了如下函数来检查最终的哈希值,但当我打印它时,它似乎不是正确的哈希值:
\n\nprivate function getFinalHash($file)\n{\n $fp = fopen($file, "r");\n $ctx = hash_init(\'sha256\');\n while (!feof($fp)) {\n $buffer = fgets($fp, 1024);\n hash_update($ctx, $buffer);\n }\n $hash = hash_final($ctx, true); print_r($hash);exit;\n fclose($fp);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n结果哈希如下: \xc5\xb8M\xc2\xa2\xe2\x80\xban\xc3\x82J\xc2\xbd\xc3\xa4\xc5\x92\xc2\xb6\\\xc3\x83&R\xc3\ xbfX\xe2\x80\x9dg\xc3\xad\xc3\x96\'\xe2\x80\x9eIoA\\C\xc3\xb7\xc3\x97\n我认为这里唯一的问题是获取文件的最终哈希值。文件大小为 5.7 MB。
\n\n我认为提供校验和的正确方法有一些问题,但我不知道应该如何处理大文件。我真的需要你的帮助。
\n设法获得所需的输出,并通过以下例程验证摘要。
<?php
$fileName = isset($argv[1]) ? $argv[1] : die("Usage : php sha256.php <<filename>> <<hash>>" . PHP_EOL);
if(!file_exists($fileName))
die("FATAL : The file specified does not exists!");
$hash = isset($argv[2]) ? $argv[2] : die("Usage : php sha256.php <<filename>> <<hash>>" . PHP_EOL);
$ctx = hash_init('sha256');
echo("INFO : Reading file $fileName ...");
$file = fopen($fileName, 'r');
while(!feof($file)){
$buffer = fgets($file, 1024);
hash_update($ctx, $buffer);
}
echo(" DONE!" . PHP_EOL);
echo("INFO : Calculating SHA256 hash of $fileName ...");
$hashRaw = hash_final($ctx, false); // Here, set the $raw_output to false
echo(" DONE!" . PHP_EOL);
echo ($hash . " INPUT " . PHP_EOL);
echo ($hashRaw . " OUTPUT " . PHP_EOL);
if($hash == $hashRaw)
echo("INFO : Hash Comparison: OK!" . PHP_EOL);
else
echo("WARN : Hash Comparison: MISMATCH!" . PHP_EOL);
echo("END" . PHP_EOL);
Run Code Online (Sandbox Code Playgroud)
您的问题是,您设置$raw_output为truein string hash_final ( HashContext $context [, bool $raw_output = FALSE ] ),这将生成原始二进制数据的输出。要么将其设置为 false 要么根本不使用它,因为它默认为false(请参阅文档)。希望这可以帮助。