Hash Generator — Python 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 Python 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: Python
CosmoDev polyglot showcase port of the ``hash`` tool.
Ported from src/tools/HashGenerator.tsx — display source, part of CosmoDev's
polyglot tool pages.
Unkeyed SHA digests via Python's standard-library ``hashlib`` module (backed
by OpenSSL). ``hashlib`` supplies the vetted, constant-time hash constructors
and returns lowercase hex via ``hexdigest()``. No third-party packages are
required.
Behavior mirrors the TypeScript reference: UTF-8 input, lowercase hex output,
and rejection of unknown algorithm names.
"""
from __future__ import annotations
import hashlib
from typing import Final
# Canonical algorithm names. The spellings match the TypeScript union so the
# same string works across every port. Each maps to a hashlib constructor.
SHA1: Final[str] = "SHA-1"
SHA256: Final[str] = "SHA-256" # default algorithm
SHA384: Final[str] = "SHA-384"
SHA512: Final[str] = "SHA-512"
DEFAULT_ALGORITHM: Final[str] = SHA256
# Dispatch table: canonical name -> hashlib constructor. Module-level so the
# supported set is visible in one place and easy to extend.
_HASH_CONSTRUCTORS = {
SHA1: hashlib.sha1,
SHA256: hashlib.sha256,
SHA384: hashlib.sha384,
SHA512: hashlib.sha512,
}
def _digest_for(algorithm: str):
"""Return the hashlib constructor for the canonical algorithm name.
Raises ValueError (not KeyError) so callers get a clear, domain-specific
message rather than a leaky lookup error.
"""
try:
return _HASH_CONSTRUCTORS[algorithm]
except KeyError:
raise ValueError(f"Unsupported hash algorithm: {algorithm}") from None
def digest(text: str, algorithm: str = SHA256) -> str:
"""Compute the digest of ``text`` and return it as lowercase hex.
``text`` is UTF-8 encoded before hashing, so the result is correct for
arbitrary Unicode (emoji, accents, CJK). An empty ``algorithm`` selects
SHA-256, standing in for the optional-parameter default the TypeScript
reference declares.
Passing the constructor (rather than the algorithm name string) as
``digestmod`` makes an unknown algorithm fail fast here instead of deep
inside ``hashlib.new``.
"""
if algorithm == "":
algorithm = DEFAULT_ALGORITHM
constructor = _digest_for(algorithm)
# text -> UTF-8 bytes; hexdigest() returns the lowercase hex string the
# TypeScript reference produces.
return constructor(text.encode("utf-8")).hexdigest()
def hash_all(text: str) -> dict[str, str]:
"""Compute every supported digest of ``text``.
Returns a dict keyed by the canonical algorithm name — the Python
equivalent of the Record the React island renders. Each hash is
independent.
"""
return {alg: digest(text, alg) for alg in (SHA1, SHA256, SHA384, SHA512)}
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 →