當前位置: 首頁> 最新文章列表> 使用hash_final 進行加密哈希計算時常見問題

使用hash_final 進行加密哈希計算時常見問題

gitbox 2025-05-27

在PHP 中, hash_final函數是用於完成一個增量式哈希上下文並返回最終哈希值的工具。它通常與hash_inithash_update等函數配合使用,用於處理大型數據或流式數據的哈希計算。然而,很多開發者在使用hash_final時會遇到一些常見的問題,本文將詳細分析這些問題並給出解決方案。

一、什麼是hash_final

hash_final的定義如下:

 string hash_final ( HashContext $context [, bool $raw_output = FALSE ] )
  • $context :通過hash_init創建的哈希上下文。

  • $raw_output :如果設為true ,輸出原始二進制數據;否則輸出小寫十六進製字符串。

簡單例子:

 $context = hash_init('sha256');
hash_update($context, 'hello');
$finalHash = hash_final($context);
echo $finalHash;

二、常見問題及解決方法

1?? 問題:多次調用hash_final失敗

現象:
hash_final一旦被調用,關聯的$context就失效了。如果嘗試再次使用相同上下文,比如:

 $context = hash_init('sha256');
hash_update($context, 'hello');
$final1 = hash_final($context);
$final2 = hash_final($context); // 錯誤!

會導致警告或錯誤。

解決方案:
如果需要重複使用上下文,請在hash_final之前調用hash_copy

 $context = hash_init('sha256');
hash_update($context, 'hello');
$contextCopy = hash_copy($context);
$final1 = hash_final($context);
$final2 = hash_final($contextCopy);

2?? 問題: raw_output參數誤用

現象:
很多人默認只取字符串輸出,忽略了$raw_output = true實際返回的是二進制。如果直接用echo輸出,會得到亂碼:

 $context = hash_init('sha256');
hash_update($context, 'hello');
$final = hash_final($context, true);
echo $final; // 可能顯示亂碼

解決方案:
要顯示可讀內容,可以用bin2hexbase64_encode

 $final = hash_final($context, true);
echo bin2hex($final);

3?? 問題:輸入數據過大導致內存溢出

現象:
當對大文件或大數據流使用hash時,直接用hash()會佔用大量內存:

 $hash = hash('sha256', file_get_contents('largefile.dat'));

解決方案:
改用hash_init + hash_update流式處理:

 $context = hash_init('sha256');
$handle = fopen('largefile.dat', 'rb');
while (!feof($handle)) {
    $data = fread($handle, 8192);
    hash_update($context, $data);
}
fclose($handle);
$finalHash = hash_final($context);

4?? 問題:跨語言哈希值不一致

現象:
同樣的輸入數據,在PHP 與其他語言(如Python、Node.js)中計算的哈希值不一致。

解決方案:
確保:

  • 輸入編碼一致(UTF-8 vs UTF-16)。

  • 是否有額外換行或空格。

  • 計算方式相同(原始vs 編碼文本)。

示例:使用PHP 計算UTF-8 編碼字符串的SHA-256 哈希:

 $context = hash_init('sha256');
hash_update($context, mb_convert_encoding($input, 'UTF-8'));
$finalHash = hash_final($context);

5?? 問題:誤用URL 處理的哈希驗證

現象:
在對URL 進行哈希驗證時,忽略了標準化,導致相同地址的哈希值不同:

 $url1 = 'https://gitbox.net/page';
$url2 = 'https://gitbox.net/page/';

解決方案:
在計算前標準化URL,例如:

 function normalizeUrl($url) {
    $parsed = parse_url($url);
    $scheme = $parsed['scheme'] ?? 'http';
    $host = $parsed['host'] ?? '';
    $path = rtrim($parsed['path'] ?? '/', '/');
    return "$scheme://$host$path";
}

$context = hash_init('sha256');
hash_update($context, normalizeUrl('https://gitbox.net/page/'));
$finalHash = hash_final($context);