Skip to content

Hash Generator — Go 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 Go 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: Go
// 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 using the Go standard library: crypto/sha1,
// crypto/sha256, and crypto/sha512 supply the vetted, constant-time hash
// implementations. SHA-384 lives in crypto/sha512 because it shares SHA-512's
// block structure with a truncated output. No third-party packages are needed.
//
// Behavior mirrors the TypeScript reference: UTF-8 input, lowercase hex
// output, and rejection of unknown algorithm names. Go string bytes are
// already the UTF-8 encoding, so no explicit encoding step is required.
package hash

import (
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"errors"
	"hash"
)

// Canonical algorithm names. The spellings match the TypeScript union so the
// same string works across every port.
const (
	SHA1   = "SHA-1"
	SHA256 = "SHA-256"
	SHA384 = "SHA-384"
	SHA512 = "SHA-512"
)

// newHasher maps an algorithm name to a factory returning a fresh hash.Hash.
// Returning a factory (not an instance) keeps the door open for streaming
// callers and matches the shape used elsewhere in the standard library.
func newHasher(algorithm string) (func() hash.Hash, error) {
	switch algorithm {
	case SHA1:
		return sha1.New, nil
	case SHA256:
		return sha256.New, nil
	case SHA384:
		return sha512.New384, nil
	case SHA512:
		return sha512.New, nil
	default:
		return nil, errors.New("unsupported hash algorithm: " + algorithm)
	}
}

// Digest computes the named digest of text and returns it as lowercase hex.
// text is interpreted as UTF-8 (Go string bytes are already that encoding).
func Digest(algorithm, text string) (string, error) {
	newHash, err := newHasher(algorithm)
	if err != nil {
		return "", err
	}

	// Write the UTF-8 bytes, then Sum(nil) to finalize. hex.EncodeToString
	// emits lowercase hex, matching the TypeScript output format exactly.
	h := newHash()
	h.Write([]byte(text))
	return hex.EncodeToString(h.Sum(nil)), nil
}

// HashAll computes every supported digest of text in one pass, returning a
// map keyed by the canonical algorithm name — the Go equivalent of the
// Record the React island renders. Each hash is independent; a failure on one
// (only possible for an unknown algorithm — not reachable here) short-circuits.
func HashAll(text string) (map[string]string, error) {
	for _, alg := range []string{SHA1, SHA256, SHA384, SHA512} {
		if _, err := newHasher(alg); err != nil {
			return nil, err
		}
	}

	out := make(map[string]string, 4)
	for _, alg := range []string{SHA1, SHA256, SHA384, SHA512} {
		hexed, err := Digest(alg, text)
		if err != nil {
			return nil, err
		}
		out[alg] = hexed
	}
	return out, nil
}

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 →