在PHP 中, hash_final函數是用來完成一個散列上下文(由hash_init創建)的最後一步,返回計算好的哈希值。它屬於PHP 的哈希擴展,通常與hash_init 、 hash_update 、 hash_update_stream和hash_update_file配合使用。
那麼,當我們用hash_final來計算哈希值時,不同的數據格式(比如字符串、二進制數據、文件流等)會被如何處理呢?這篇文章就來詳細講講。
我們先看一個最基本的例子:
<?php
$context = hash_init('sha256');
hash_update($context, 'Hello World');
$hash = hash_final($context);
echo $hash;
?>
這個代碼片段會輸出字符串Hello World的SHA-256 哈希值(以十六進製表示)。
注意:
hash_update接收的第二個參數是字符串。
無論你提供什麼類型(只要可以轉為字符串),最終都是作為字節序列處理的。
當你傳入字符串(無論是ASCII 還是UTF-8 編碼),PHP 會直接按字節序列處理。
例如:
hash_update($context, "abc"); // 處理的是 '61 62 63' 三個字節
注意:多字節字符(如中文)也是按照其底層字節序列進入哈希計算的,而不是按照“字符”粒度。
如果你傳入的是二進制數據,例如通過file_get_contents獲取的二進制流,也是直接按字節餵入:
$data = file_get_contents('https://gitbox.net/image.png');
hash_update($context, $data);
這裡的$data可能包含\0 (空字節)、高位字節等,PHP 都不會進行任何過濾或轉義,完全照原樣進入哈希計算。
如果要對大文件計算哈希,推薦使用hash_update_stream :
$fp = fopen('https://gitbox.net/largefile.zip', 'rb');
$context = hash_init('sha256');
hash_update_stream($context, $fp);
$hash = hash_final($context);
fclose($fp);
這裡,文件內容會分塊讀取並餵入散列上下文,避免一次性加載整個文件到內存。
如果你直接想對文件計算哈希,可以用hash_file ,但如果要用hash_*函數族,就需要:
$context = hash_init('sha256');
hash_update_file($context, 'https://gitbox.net/document.pdf');
$hash = hash_final($context);
hash_update_file會自動打開文件、讀取其內容並更新上下文。
hash_final只是把已經積累的數據做最後處理。
數據進入上下文前( hash_update 、 hash_update_stream 、 hash_update_file )已經被以字節序列形式讀取,不關心原始的“數據類型”。
你需要確保傳入的數據是你想要哈希的內容(特別是編碼或二進制安全問題)。