MD5 and SHA1 are two old friends that PHP has kept around for a very long time. You will still find md5() and sha1() in legacy applications, integrations, checksum code, and the occasional database column that nobody wants to touch.
If you are comparing MD5 vs SHA1 for new PHP code, however, there is an important point to know first: neither algorithm should be your default choice for security-sensitive hashing today.
That does not make the PHP functions useless. Understanding their output, differences, and limitations is still useful when maintaining existing systems or working with an external protocol that requires one of these hashes.
Quick answer: MD5 vs SHA1 in PHP
PHP provides md5() and sha1() for generating hashes from strings. Both functions are fast and deterministic. The same input produces the same hash every time.
| Feature | MD5 | SHA1 |
|---|---|---|
| PHP function | md5() |
sha1() |
| Digest size | 128 bits | 160 bits |
| Default PHP output | 32 hexadecimal characters | 40 hexadecimal characters |
| Raw binary output | 16 bytes | 20 bytes |
| Suitable for passwords | No | No |
| Recommended for new security-sensitive code | No | No |
SHA1 has a larger digest than MD5, but that does not make SHA1 a good modern security choice. Both algorithms have known collision weaknesses. NIST recommends moving away from SHA-1 in favor of SHA-2 or SHA-3 for cryptographic protection.
For general-purpose cryptographic hashing in PHP, use an appropriate modern algorithm such as SHA-256 through hash(). For passwords, do not replace MD5 or SHA1 with a plain SHA-256 hash. PHP provides password_hash() and password_verify() specifically for password storage and verification.
One more distinction matters here. A hash is not encryption. There is no PHP function that can simply decrypt an MD5 or SHA1 digest back to its original value. Weak password hashes are cracked in practice by trying candidate passwords, hashing them, and comparing the results. Because MD5 and SHA1 are designed to be fast, attackers can perform those guesses very quickly.
Generate MD5 and SHA1 hashes in PHP
The basic PHP functions are straightforward. Pass a string to md5() or sha1(), and PHP returns the hash as a lowercase hexadecimal string.
<?php
$text = 'PHPpot';
$md5Hash = md5($text);
$sha1Hash = sha1($text);
echo 'MD5: ' . $md5Hash . PHP_EOL;
echo 'SHA1: ' . $sha1Hash . PHP_EOL;
The MD5 result contains 32 hexadecimal characters. The sha1() function returns 40.
This is sometimes confused with the actual digest size. MD5 is not a 32-bit hash. Its digest is 128 bits. The 32-character value is simply the hexadecimal representation of those 128 bits. Likewise, SHA1 produces a 160-bit digest represented by 40 hexadecimal characters.
Hexadecimal output vs raw binary output
Both functions accept an optional second argument named binary. It is false by default, so PHP normally returns the readable hexadecimal form.
Set it to true to receive the raw binary digest instead.
<?php
$text = 'PHPpot';
$md5Binary = md5($text, true);
$sha1Binary = sha1($text, true);
echo strlen($md5Binary) . PHP_EOL; // 16 bytes
echo strlen($sha1Binary) . PHP_EOL; // 20 bytes
The raw form can be useful when a protocol or storage format specifically expects binary data. For normal logging, debugging, URLs, or database values, the hexadecimal form is usually easier to work with.
Do not print raw hashes directly into an HTML page and expect readable output. They can contain arbitrary byte values. If you need a printable representation, keep the default hexadecimal output or encode the binary value explicitly.
Hash the same value and compare the result
Hash functions are deterministic. If the input does not change, the generated hash does not change either.
<?php
$expectedHash = md5('PHPpot');
$receivedHash = md5('PHPpot');
if (hash_equals($expectedHash, $receivedHash)) {
echo 'The hashes match.';
}
For ordinary non-secret checksums, a direct equality comparison may be sufficient. When comparing a security-sensitive known hash with a calculated value, hash_equals() provides a timing-attack-safe string comparison.
The comparison method does not make MD5 itself secure. It only makes the comparison safer. The strength of the hashing algorithm and the way the result is compared are separate concerns.
MD5 vs SHA1 security
MD5 and SHA1 were designed as cryptographic hash functions, but both are now considered broken for collision resistance.
A collision happens when two different inputs produce the same hash. That should be extremely difficult for a secure cryptographic hash. Practical collision attacks have been demonstrated against both MD5 and SHA1, so neither should be chosen for new applications that depend on collision resistance.
SHA1 is stronger than MD5 in the historical sense. It has a longer digest and resisted attacks for longer. But choosing SHA1 instead of MD5 today is a little like replacing one old lock with a slightly better old lock. It does not solve the modern security problem.
Do not use MD5 or SHA1 for passwords
Password hashing has different requirements from ordinary data hashing. A password hash should be deliberately slow and should use a unique salt so that large-scale guessing attacks are expensive.
MD5 and SHA1 are intentionally fast. That makes them a poor fit for password storage.
Use PHP’s password API instead:
<?php
$password = 'my-secret-password';
$hash = password_hash($password, PASSWORD_DEFAULT);
if (password_verify($password, $hash)) {
echo 'Password is valid.';
}
PASSWORD_DEFAULT lets PHP use its recommended default password algorithm. It also allows the default to improve in future PHP versions without requiring you to redesign your application code.
Do not manually add a salt and then hash the password with MD5, SHA1, or SHA256. password_hash() handles the salt and password-hashing format for you.
Use SHA-256 when you need a modern general-purpose hash
If you need a cryptographic digest for data rather than passwords, PHP’s hash() function supports modern algorithms such as SHA-256.
<?php
$data = 'PHPpot';
$hash = hash('sha256', $data);
echo $hash;
SHA-256 belongs to the SHA-2 family and is a much better default than MD5 or SHA1 for new cryptographic hashing requirements.
A practical example is PHPpot’s secure password reset implementation, which hashes reset tokens with SHA-256 before storing them in the database.
That does not mean SHA-256 should be used for every hashing problem. Passwords still belong with password_hash(). Authentication codes should normally use HMAC. File checksums and protocol compatibility may have their own requirements.
The important part is to choose the hash for the job rather than simply choosing the function with the longest output.
Generate MD5 and SHA1 hashes for files
PHP also provides file-specific functions when you need to calculate a hash from a file instead of first reading the whole file into a string.
<?php
$file = __DIR__ . '/sample.txt';
$md5Hash = md5_file($file);
$sha1Hash = sha1_file($file);
echo 'MD5: ' . $md5Hash . PHP_EOL;
echo 'SHA1: ' . $sha1Hash . PHP_EOL;
This is useful when you are working with an old API, manifest, or download system that explicitly expects an MD5 or SHA1 checksum.
For new integrity checks, prefer a stronger algorithm:
<?php
$file = __DIR__ . '/sample.txt';
$sha256Hash = hash_file('sha256', $file);
echo $sha256Hash;
One practical point is easy to miss: a checksum can help detect whether data changed, but an unkeyed hash alone does not prove who created the data. If an attacker can replace both the file and its published checksum, the comparison tells you very little.
When MD5 or SHA1 may still appear in PHP code
You may still need MD5 or SHA1 when maintaining an existing system. Common cases include a legacy API, an older database schema, a protocol specification, or a third-party service that requires a particular digest format.
In those cases, compatibility may force the algorithm choice. The important part is to avoid treating that requirement as a recommendation for new security-sensitive code.
For example, if an external service requires SHA1 for a request signature defined by its protocol, changing your side to SHA-256 will simply break the integration. The right long-term fix is to move to a newer protocol version when one is available.
Common MD5 and SHA1 mistakes in PHP
Most problems around these functions are not syntax problems. They come from assumptions about what the returned value represents.
- Calling MD5 a 32-bit hash: MD5 produces 128 bits. Its default hexadecimal representation is 32 characters long.
- Calling SHA1 a 40-bit hash: SHA1 produces 160 bits. PHP normally displays it as 40 hexadecimal characters.
- Using SHA1 because it is stronger than MD5: SHA1 is also deprecated for new cryptographic security uses.
- Using a plain SHA-256 hash for passwords: use
password_hash()instead. - Expecting a hash to be reversible: hashing is one-way. It is not encryption.
- Comparing raw binary output as if it were text: binary digests can contain non-printable bytes.
If you are maintaining legacy code, these distinctions matter more than the small syntax difference between md5() and sha1().
Which one should you use?
If the choice is strictly between MD5 and SHA1 for a new security-sensitive feature, the answer is neither.
Use MD5 or SHA1 only when you have a specific compatibility reason, such as an existing protocol or legacy system that requires it. For new general-purpose cryptographic hashing, prefer SHA-256 or another current algorithm supported by hash().
For passwords, use password_hash() and password_verify(). That is a separate problem and should not be solved with a fast general-purpose hash.
FAQ
Is SHA1 better than MD5 in PHP?
SHA1 has a larger 160-bit digest compared with MD5’s 128-bit digest, but both have known collision weaknesses. SHA1 should not be treated as a secure modern replacement for MD5.
Why does MD5 return 32 characters?
MD5 produces a 128-bit digest. PHP displays that digest as hexadecimal by default. Each hexadecimal character represents 4 bits, so 128 bits become 32 hexadecimal characters.
Why does SHA1 return 40 characters?
SHA1 produces a 160-bit digest. Its hexadecimal representation therefore contains 40 characters.
Can MD5 or SHA1 be decrypted?
No. They are hash functions, not encryption algorithms. There is no decryption key. Weak hashes can sometimes be discovered by guessing likely inputs and comparing their hashes, but that is not decryption.
Can I use SHA-256 for passwords instead?
Not as a plain hash. SHA-256 is still designed to be fast. For password storage, use PHP’s password_hash() API, which is designed specifically for that purpose.
Are MD5 and SHA1 still available in PHP 8?
Yes. PHP still provides md5(), sha1(), md5_file(), and sha1_file(). Their availability does not mean they are recommended for new security-sensitive code.
Conclusion
MD5 and SHA1 are still useful to understand because they remain common in older PHP applications and compatibility-driven integrations.
The key difference is simple: MD5 produces a 128-bit digest, while SHA1 produces a 160-bit digest. But for modern development, digest size is not the deciding factor. Both algorithms have known collision weaknesses and should generally be avoided for new cryptographic security features.
Use modern hashing algorithms for general data hashing, and use PHP’s password API for passwords. Keep MD5 and SHA1 where compatibility requires them, not where new design decisions are being made.
i want to write a code for fingerprint recognition. how to use these md5() & sha1() functions in my code.
MD5 and SHA1 are not suitable for fingerprint recognition. They are hashing functions and cannot compare fingerprint images or identify fingerprint patterns.
For fingerprint recognition, you normally need a fingerprint scanner or image, feature extraction such as minutiae points, and a matching algorithm or fingerprint recognition library.
You may use hashing only after recognition, for example to protect or verify stored data, but not to perform the fingerprint matching itself.
These functions are not suitable for password hashing to protect password from a hacker. Because the code returned by these functions are easily breakable.
Yes Daniel, you are absolutely correct. I have written the same in my article above. Thanks for reiterating here.