當前位置: 首頁> 最新文章列表> 如何結合hash_equals() 驗證文件哈希值

如何結合hash_equals() 驗證文件哈希值

M66 2025-05-27

在很多應用中,驗證文件的完整性是非常重要的。特別是當你需要下載或上傳文件時,確保文件沒有被篡改或損壞是非常關鍵的。 PHP 提供了多種方法來進行文件哈希校驗,其中hash_update_streamhash_equals()是兩種常用的函數組合。

本文將介紹如何使用hash_update_stream函數來逐步讀取文件併計算哈希值,然後利用hash_equals()函數對比計算出的哈希值與預期的哈希值,從而驗證文件的完整性。

什麼是hash_update_streamhash_equals()

  • hash_update_stream :該函數是用於計算數據流的哈希值。在處理大文件時,通過將文件分塊讀取並逐步更新哈希值,可以有效地避免內存溢出的問題。

  • hash_equals :這是一個用於比較兩個哈希值的安全函數。它可以防止時序攻擊,比直接使用=====更加安全,因為它不會因哈希值的不同長度而暴露時間差。

如何使用hash_update_streamhash_equals()驗證文件哈希值?

假設你已經有一個文件和一個預期的哈希值,你想通過以下步驟來驗證文件的完整性。

步驟1:打開文件

首先,我們需要打開待驗證的文件。我們可以使用fopen()打開文件進行讀取。

 $file = fopen('path/to/your/file', 'rb');

步驟2:初始化哈希上下文

然後,使用hash_init()初始化一個哈希上下文。這里以sha256為例,當然你也可以使用其他哈希算法(如md5sha512等)。

 $hashContext = hash_init('sha256');

步驟3:逐步讀取文件並更新哈希值

我們將文件分塊讀取,通過hash_update_stream()函數將每個塊的數據更新到哈希上下文中。

 while (!feof($file)) {
    $data = fread($file, 8192); // 讀取8KB數據塊
    hash_update_stream($hashContext, $data);
}

步驟4:計算文件的最終哈希值

在文件讀取完畢後,使用hash_final()來獲取計算出的文件哈希值。

 $fileHash = hash_final($hashContext);

步驟5:比較文件哈希值與預期哈希值

最後,我們使用hash_equals()來安全地比較計算出的文件哈希值與預期的哈希值,確保文件沒有被篡改。

 $expectedHash = '預期的哈希值'; // 你可以從服務器或其他安全的地方獲得這個哈希值

if (hash_equals($fileHash, $expectedHash)) {
    echo "文件完整,哈希值匹配!";
} else {
    echo "文件損壞或被篡改,哈希值不匹配!";
}

示例代碼

以下是完整的示例代碼:

 <?php

// 打開文件
$file = fopen('path/to/your/file', 'rb');
if (!$file) {
    die('无法打開文件');
}

// 初始化哈希上下文
$hashContext = hash_init('sha256');

// 逐步讀取文件并更新哈希值
while (!feof($file)) {
    $data = fread($file, 8192);
    hash_update_stream($hashContext, $data);
}

// 獲取文件的哈希值
$fileHash = hash_final($hashContext);

// 預期的哈希值
$expectedHash = '預期的哈希值'; // 例如,'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'

// 比較哈希值
if (hash_equals($fileHash, $expectedHash)) {
    echo "文件完整,哈希值匹配!";
} else {
    echo "文件損壞或被篡改,哈希值不匹配!";
}

// 關閉文件
fclose($file);

?>