【问题标题】:How to calculate SHA256 of large files in php如何在php中计算大文件的SHA256
【发布时间】:2023-04-10 14:55:01
【问题描述】:

我想在 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÷× 我认为这里唯一的问题是获取文件的最终哈希值。文件大小为 5.7 MB。

我认为提供校验和的正确方式与提供校验和有关,但我不知道应该如何处理大文件。我真的需要你的帮助。

【问题讨论】:

标签: php hash sha256


【解决方案1】:

设法获得所需的输出,并获得通过以下例程验证的摘要。

<?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);

您的问题是,您将string hash_final ( HashContext $context [, bool $raw_output = FALSE ] ) 中的$raw_output 设置为true,这会将输出生成为原始二进制数据。将其设置为 false 或根本不使用它,因为它默认为 false (see the doc)。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2017-08-19
    • 1970-01-01
    • 2020-09-01
    • 2011-12-12
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2018-01-27
    相关资源
    最近更新 更多