Skip to content

Hash Generator — JavaScript source

Compute SHA-1, SHA-256, SHA-384 and SHA-512 hashes of any text at once, using the browser's native SubtleCrypto. Copy each digest. 100% client-side.

This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.

/**
 * hash - SHA-1 / SHA-256 / SHA-384 / SHA-512 digest of a UTF-8 string.
 *
 * Language: JavaScript (Web Crypto API / SubtleCrypto)
 * CosmoDev polyglot showcase port of the `hash` tool.
 * Ported from src/tools/HashGenerator.tsx - display source, part of CosmoDev's
 * polyglot tool pages.
 *
 * Pure logic - no DOM, no React. Computes the four digests the live tool
 * shows (SHA-1, SHA-256, SHA-384, SHA-512), each as lowercase hex, via the
 * same WebCrypto surface the canonical TypeScript implementation uses; shown
 * here without type annotations. Behavior matches exactly: UTF-8 input,
 * lowercase hex output, async only because SubtleCrypto is. Requires a secure
 * context (https or localhost).
 */

// Supported hash algorithms. These spellings are SubtleCrypto's own algorithm
// names and are shared verbatim across every language port.
const HASH_ALGORITHMS = ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'];

/**
 * Lowercase hexadecimal encoding of an ArrayBuffer.
 *
 * Spreading the byte view into a plain array lets map/join build one string
 * with no trailing separator; each byte is zero-padded to two hex digits.
 */
function toHex(buf) {
  return Array.from(new Uint8Array(buf))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('');
}

/**
 * Compute the named digest of `text` and return it as lowercase hex.
 *
 * The input is UTF-8 encoded via TextEncoder before hashing, so the result is
 * correct for arbitrary Unicode (emoji, accents, CJK) - not just Latin-1.
 *
 * @param {string} algorithm One of HASH_ALGORITHMS.
 * @param {string} text      The payload to hash.
 * @returns {Promise<string>} Lowercase hex digest.
 */
export async function digest(algorithm, text) {
  const buf = await crypto.subtle.digest(algorithm, new TextEncoder().encode(text));
  return toHex(buf);
}

/**
 * Compute every supported digest for `text` in one pass.
 *
 * Mirrors what the island renders: an object keyed by algorithm name. The
 * four digests run concurrently via Promise.all - they share no state.
 *
 * @param {string} text The payload to hash.
 * @returns {Promise<Record<string, string>>} Map of algorithm name -> hex digest.
 */
export async function hashAll(text) {
  const entries = await Promise.all(
    HASH_ALGORITHMS.map(async (a) => [a, await digest(a, text)]),
  );
  return Object.fromEntries(entries);
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →