In PHP, hash_final() is an important function provided by hash extension, which is specifically used to complete hash calculation based on context ( hash context ). When using it, many developers simply regard it as a function of "take the result", and ignore its output characteristics and best use. This article will analyze the return value of hash_final() in detail, discuss its characteristics, possible misuses, and application techniques in actual development.
First, let’s take a look at the basic usage.
<?php
$context = hash_init('sha256');
hash_update($context, 'Hello, World!');
$result = hash_final($context);
echo $result;
?>
In this example, hash_final() returns a hexadecimal string calculated by the sha256 algorithm . This is the default output format of hash_final() .
?? Note : Once hash_final() is called, the context will be "closed" and can no longer be used to continue processing with hash_update() or hash_final() . If you need to repeat the calculation, you must use hash_copy() or hash_init() .
There are two forms of the return value of hash_final() :
Default (hexadecimal string) : Easy to display or store directly.
Original binary format : more suitable for low-level processing, such as depositing into a database, comparing with other binary data, etc.
To get the binary format, you can pass the true parameter:
<?php
$context = hash_init('sha256');
hash_update($context, 'Hello, World!');
$binaryResult = hash_final($context, true);
echo bin2hex($binaryResult); // usebin2hexView the hexadecimal representation of the original binary
?>
? Tip : If you want to store hash in text environments such as URLs, databases, JSON, etc., use the default (hexadecimal) output; if it is used for low-level encryption, signatures, etc., it is recommended to use binary format.
1?? Misunderstanding 1: hash_final() can be called multiple times <br> Many developers think that they can haveh_final() multiple times, but in fact, the context is discarded after it is called, and an error will be reported after it is called. The solution is to use hash_copy() :
<?php
$context = hash_init('sha256');
hash_update($context, 'data1');
$copy = hash_copy($context);
hash_update($context, 'data2');
$result1 = hash_final($copy);
$result2 = hash_final($context);
2?? Misunderstanding 2: Direct comparison between original binary and hexadecimal <br> The original binary ( true ) and hexadecimal (default) are in different encoding formats, and direct comparison will cause an error. When comparing, you need to unify the format, such as using bin2hex() .
? Tip 1: File segmented hashing
When you want to process large files, you can use segmented reading to combine hash_update() and hash_final() to avoid reading into memory at one time.
<?php
$context = hash_init('sha256');
$handle = fopen('/path/to/largefile.zip', 'rb');
while (!feof($handle)) {
$data = fread($handle, 8192);
hash_update($context, $data);
}
fclose($handle);
$hash = hash_final($context);
echo $hash;
?>
? Tip 2: Use with HMAC
HMAC is a message authentication code based on the key. PHP provides hash_hmac() for easy calling, but if you use context, you can manually complete more complex processes.
<?php
$context = hash_init('sha256', HASH_HMAC, 'secretkey');
hash_update($context, 'Important message');
$hmac = hash_final($context);
echo $hmac;
?>
In actual development, the results of hash_final() often need to be combined with usage scenarios such as network transmission, interface calls, signature verification, etc. For example, when generating a download link, you can:
<?php
$file = 'installer.exe';
$secret = 'mysecret';
$context = hash_init('sha256', HASH_HMAC, $secret);
hash_update($context, $file);
$signature = hash_final($context);
$url = 'https://gitbox.net/download/' . $file . '?sig=' . $signature;
echo $url;
?>
In the link generated in this way, the sig parameter is the secure signature obtained with hash_final() , and the backend can verify the legitimacy of the download request in the same way.