Signature
sha1(string $string, bool $binary = false): stringPurpose
sha1() calculates the SHA-1 digest of a string. A digest is a fixed-size fingerprint: the same input always gives the same output, and a tiny change in the input produces a completely different digest. Typical uses are building cache keys, comparing content against a known checksum, or interoperating with an older system that still publishes SHA-1 values.
The PHP manual warns that sha1() should not be used to secure passwords, because the algorithm is fast, which makes guessing attacks cheap. For passwords, use password_hash() and password_verify() instead.
Signature
Parameters and defaults
$stringis the input. PHP strings are byte sequences, so the digest is computed over the raw bytes. A UTF-8 string and the same text in another encoding produce different digests.$binarydefaults tofalse. Withfalseyou get a 40-character lowercase hexadecimal string. Withtrueyou get the raw digest, which is exactly 20 bytes long and usually not printable.
Return value and failure cases
The function always returns a string. There is no false return and no error value for ordinary string input, including the empty string. The only failures come from PHP's type rules: passing an array or an object without a string conversion throws a TypeError, and under declare(strict_types=1) passing an integer also throws instead of being converted to a string.
Example 1: hexadecimal digests
The default output is easy to print, log or store. Even an empty string has a well-defined digest.
echo sha1('abc'), "\n";
echo sha1(''), "\n";a9993e364706816aba3e25717850c26c9cd0d89d da39a3ee5e6b4b0d3255bfef95601890afd80709
Example 2: comparing against a stored checksum
When you compare a computed digest with a known value, use hash_equals(). It compares in constant time, which avoids leaking information about where two strings first differ. This matters most when the known value is secret-adjacent, such as a token.
$stored = 'd0be2dc421be4fcd0172e5afceea3970e2f3d940';
$input = 'apple';
echo json_encode(['match' => hash_equals($stored, sha1($input)), 'length' => strlen(sha1($input))]);{"match":true,"length":40}Example 3: raw binary output
The raw form is half the size of the hex form because each byte is shown as two hex characters. Use bin2hex() to convert it back to readable text.
$raw = sha1('abc', true);
echo json_encode(['rawLength' => strlen($raw), 'hex' => bin2hex($raw), 'same' => bin2hex($raw) === sha1('abc')]);{"rawLength":20,"hex":"a9993e364706816aba3e25717850c26c9cd0d89d","same":true}Edge cases
- Empty string: it is valid input and returns the fixed digest
da39a3ee5e6b4b0d3255bfef95601890afd80709. - Binary data: strings with null bytes or invalid UTF-8 are fine, because the function reads bytes, not characters.
- Numbers: an integer is converted to its decimal string when strict typing is off, so
sha1(123)hashes the text123. Be explicit with a cast or a string literal if you want to avoid surprises. - Whitespace and case:
'apple','Apple'and'apple 'all have different digests. Normalize input before hashing if your application treats them as equal. - Output case: the hex result is lowercase. If you receive an uppercase checksum from elsewhere, lowercase it before comparing.
Common mistakes
- Hashing passwords with it. A plain fast hash without a per-user salt and a deliberately slow algorithm is a poor fit for credentials. Use
password_hash(). - Treating a hash as encryption. A digest cannot be reversed by design, so you cannot recover the original text from it. It is also not a way to hide small, guessable inputs, since an attacker can hash candidates and compare.
- Comparing with
==or===for secrets. Ordinary comparison is not constant time. Usehash_equals()with the known value as the first argument. - Assuming the binary flag gives readable text. The raw result may contain control characters. Do not echo it into HTML or JSON without encoding it, for example with
bin2hex()orbase64_encode(). - Storing the raw digest in a text column. The 20 bytes may not survive a text encoding. Store the 40-character hex form, or use a binary column.
- Choosing it for new security designs. If you are free to choose an algorithm,
hash()lets you pick a different one, such assha256, with the same basic call style.
Related functions
hash()generates digests with many algorithms, selected by name.password_hash()andpassword_verify()are the right tools for password storage.hash_equals()performs timing-safe string comparison.bin2hex()converts raw bytes to hexadecimal text.md5()andcrc32()are other quick checksum functions with their own trade-offs.
Recap
sha1() turns a string into a 40-character hex digest, or a 20-byte raw digest when $binary is true. It is deterministic and accepts any bytes, including an empty string. Compare results with hash_equals(), and never rely on it to protect passwords.
Tested examples
echo sha1('abc'), "\n";
echo sha1(''), "\n";a9993e364706816aba3e25717850c26c9cd0d89d da39a3ee5e6b4b0d3255bfef95601890afd80709
$stored = 'd0be2dc421be4fcd0172e5afceea3970e2f3d940';
$input = 'apple';
echo json_encode(['match' => hash_equals($stored, sha1($input)), 'length' => strlen(sha1($input))]);{"match":true,"length":40}
$raw = sha1('abc', true);
echo json_encode(['rawLength' => strlen($raw), 'hex' => bin2hex($raw), 'same' => bin2hex($raw) === sha1('abc')]);{"rawLength":20,"hex":"a9993e364706816aba3e25717850c26c9cd0d89d","same":true}