From text to bytes
Whatever you type is first converted to UTF-8 bytes — a real difference from "characters": an emoji or accented letter can take up several bytes, and SHA-256 hashes those bytes, not an abstract idea of "characters".
const bytes = new TextEncoder().encode(text); // UTF-8, not UTF-16
const digest = await crypto.subtle.digest("SHA-256", bytes);
// digest is a 32-byte ArrayBuffer — hex-encoded above for displaydigest() takes just an algorithm name and the bytes — there's no key, no options object. "SHA-256" is the only string this tool passes; WebCrypto also accepts "SHA-1", "SHA-384", and "SHA-512".
Padding to a whole number of blocks
SHA-256 only processes complete 512-bit (64-byte) blocks. Your message is padded: a single 1 bit is appended, then as many 0 bits as needed, then the original bit-length as a 64-bit number — leaving a result that's an exact multiple of 512 bits. For a short string like this tool's defaults, that's a single block.
// Same line as above — padding isn't something the caller does.
const digest = await crypto.subtle.digest("SHA-256", bytes);WebCrypto never exposes a raw "add padding" or "process block" step. You hand digest() the unpadded message and get the final hash back; the padding and block-splitting happen natively, out of JavaScript's reach.
64 rounds of mixing
That padded block runs through 64 rounds of bitwise rotation, shifting, and modular addition, updating eight 32-bit working variables derived from SHA-256's fixed initial constants. The result becomes the chaining value fed to the next block — the Merkle-Damgård construction covered in the Hash functions module — or, since there's only one block here, the digest itself.
// Still the same line — the 64 compression rounds are the bulk of
// what happens between calling digest() and its promise resolving.
const digest = await crypto.subtle.digest("SHA-256", bytes);This is why SHA-256 is a single async call rather than a class you instantiate and feed chunks to (compare Node's crypto.createHash, which does expose an update() step) — the browser API only gives you the final answer.
Why editing one character changes everything
Each of those 64 rounds is designed to spread every input bit's influence across the entire internal state within a handful of rounds, the same avalanche principle behind AES. Change a single UTF-8 byte at the very start, and by round 64 essentially every one of the 256 output bits has an even chance of flipping — exactly what you see comparing the two digests above.