gizmobench
BrowseDaily

Bcrypt Generator

Make a bcrypt hash of a password with a new random salt and a selected $2a$, $2b$ or $2y$ prefix, or check a candidate password against an existing hash. Choose which workflow appears first. Generation runs at cost 4–14 and verification at cost 4–16, in a cancellable browser worker. Passwords longer than 72 UTF-8 bytes are flagged before the first 72 bytes are used.

generate

cost 10

0 characters, 0 of 72 bytes

10 = 2^10 = 1,024 rounds

salt16 random bytes, new each time

the hash appears here

elapsednot run yet

verify

paste a hash, or generate one

0 characters, 0 of 72 bytes

reads$2a$, $2b$ and $2y$ hashes; Generate is set to $2a$

costtaken from the hash, 4 to 16 here

no result yet

elapsednot run yet

each step in cost doubles the rounds: 4 is 16, 10 is 1,024, 14 is 16,384, 16 is 65,536

Cost
10, 1,024 rounds
Password
0 of 72 bytes
Verify
not run
Elapsed
not run

  • Published vector, password abc$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i
    press Run to check it in this browser
  • 72 a's, then 72 a's plus é73 characters, 74 bytes in UTF-8, one salt for both
    press Run to hash both here
  • Cancel at cost 14an example password, cancelled 200 ms in
    press Run to start one and cancel it

Accuracy. Generate computes each hash on this device with hash-wasm 4.12.0 in a worker, using a new 16-byte salt from crypto.getRandomValues, and writes your selected $2a$, $2b$ or $2y$ prefix; nothing typed here is sent or stored. bcrypt reads at most 72 bytes of UTF-8, so a longer password is flagged and bytes past the 72nd do not change the hash. Cost runs from 4 to 14 when generating and up to 16 when verifying, each step doubling the rounds; the elapsed time is this browser's and says nothing about password strength.

Common questions

Is my password sent anywhere?
No. The hash is computed in a Web Worker that this page starts, by hash-wasm 4.12.0 loaded from this site, and the page makes no request carrying your password. It is not stored and never goes into the address bar. The one thing remembered, in this browser's local storage, is the cost you last chose.
Why does bcrypt ignore everything after 72 bytes?
bcrypt's key setup cycles the password through Blowfish's 18 subkeys of 4 bytes each, 72 bytes in all, so nothing after the 72nd byte of the UTF-8 text reaches the hash. The letter a is one byte, é is two, € is three and most emoji are four, so the limit can arrive well before 72 characters. This page counts bytes as you type and flags a longer password. The 72-byte case under the tool hashes 72 a's and 72 a's plus é with one salt and gets the same hash for both.
Why is the hash different every time for the same password?
Each hash Generate makes gets a new 16-byte salt from crypto.getRandomValues, written as the 22 characters after the cost. A different salt gives a different hash, and verify reads the salt back out of the hash, so every one of them checks as true against the password.
What is the difference between $2a$, $2b$ and $2y$?
They mark revisions of bcrypt. This page can generate any of these three output prefixes and verify them. For the NUL-free UTF-8 passwords prepared here, limited to the first 72 bytes, the supported revisions share the same salt/checksum computation. The engine computes $2a$ and the chosen compatible prefix is written on that result. The worker refuses a non-UTF-8 0xFF safety-case byte for alternate prefixes. This is not a promise that arbitrary historical binary-password records are interchangeable. $2x$ hashes, which identify the old buggy computation, are refused.
How do I read the parts of a bcrypt hash?
The first four characters are the version, such as $2a$. The two digits after it are the cost, then a $: 10 means 2^10, or 1,024 rounds. The next 22 characters are the salt and the last 31 are the hash itself, both in bcrypt's own base64 alphabet. Every new hash on this page is split into those four parts under it.
How long does each cost take?
Each step in cost doubles the rounds: 4 is 16, 10 is 1,024 and 14 is 16,384. In a test in Chromium on an Apple M4 Pro Mac, cost 10 took about 60 ms and cost 14 about 0.9 s. The page shows the time your own browser took after every hash. That time says nothing about how strong a password is.
Why does verify stop at cost 16?
Every step doubles the work: cost 17 is 131,072 rounds, 8 times cost 14, and cost 20 is 64 times, about a minute at the speed above. This page bounds a check at cost 16: it verifies hashes from cost 4 to 16 and names the cost of any hash above that instead of running it.
Can this decrypt or reverse a bcrypt hash?
No. bcrypt is one-way. Verify answers one question: does the password you typed match this hash, true or false.
What do Cancel and Clear do?
Cancel terminates the worker at once, so no hash comes back, and empties the password on that side. Clear empties the password and the result; on the verify side it also puts the generated hash back in the hash field. The cancel case under the tool starts a cost-14 hash and cancels it 200 ms in.
How do I verify a password against a bcrypt hash?
Choose Verify first, paste the candidate password and the complete 60-character $2a$, $2b$ or $2y$ hash, then press Verify. Cost and salt come from that stored hash, so you do not enter a separate salt. A match is true and a mismatch is false. Editing either input clears the old result, and Cancel stops the worker. This checks one known candidate; it does not recover a password.
Can I supply a salt, generate a password, or export an htpasswd entry?
Generate always chooses a new random 16-byte salt. The output shows the encoded salt, but there is no custom-salt input or standalone salt generator. This tool hashes a password you supply; Password Generator creates a new plaintext password. It copies the bcrypt hash, without a username:hash wrapper or htpasswd file export. Application configuration, Laravel/Spring integration and WordPress password records require their own format and runtime.

Generate computes each hash on this device with hash-wasm 4.12.0 in a worker, using a new 16-byte salt from crypto.getRandomValues, and writes your selected $2a$, $2b$ or $2y$ prefix; nothing typed here is sent or stored. bcrypt reads at most 72 bytes of UTF-8, so a longer password is flagged and bytes past the 72nd do not change the hash. Cost runs from 4 to 14 when generating and up to 16 when verifying, each step doubling the rounds; the elapsed time is this browser's and says nothing about password strength.