Hash Type Identifier — TypeScript source
Identify the likely hash algorithm of a hash string by its length and character set - MD5, SHA-1/2/3, BLAKE, CRC32, NTLM, bcrypt, Argon2 and more.
This is the TypeScript implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Pure hash-type identification - no React, no DOM, deterministic.
// Classifies a string's charset and suggests likely hash algorithms by
// length. Never throws.
export interface HashMatch {
name: string;
bitLength: number; // hex length * 4, where applicable
}
export type HashCharset = 'hex' | 'base64' | 'bcrypt' | 'argon2' | 'unknown';
export interface HashInfo {
input: string;
cleaned: string; // trimmed
length: number;
charset: HashCharset;
candidates: HashMatch[];
}
// Hex candidates keyed by hex-string length.
const HEX_BY_LENGTH: Record<number, string[]> = {
8: ['CRC32', 'Adler-32'],
16: ['MySQL 3.x', 'CRC64'],
32: ['MD5', 'MD4', 'NTLM', 'LM', 'MD2', 'RIPEMD-128', 'HAVAL-128'],
40: ['SHA-1', 'RIPEMD-160', 'HAVAL-160', 'MySQL 5.x (SHA1(SHA1))', 'Tiger-160'],
56: ['SHA-224', 'SHA3-224', 'BLAKE2s-224', 'HAVAL-224'],
64: ['SHA-256', 'SHA3-256', 'BLAKE2s-256', 'RIPEMD-256', 'Skein-256'],
96: ['SHA-384', 'SHA3-384', 'BLAKE2b-384'],
128: ['SHA-512', 'SHA3-512', 'BLAKE2b-512', 'Whirlpool', 'Skein-512'],
};
// Base64 candidates keyed by length (decoded-byte length × 4/3 rounded).
const BASE64_BY_LENGTH: Record<number, string[]> = {
24: ['MD5 (base64)'],
28: ['SHA-1 (base64)'],
44: ['SHA-256 (base64)'],
88: ['SHA-512 (base64)'],
};
export function detectCharset(s: string): HashCharset {
if (/^\$2[abxy]?\$/.test(s)) return 'bcrypt';
if (/^\$argon2(id|i|d)?\$/.test(s)) return 'argon2';
if (/^[0-9a-fA-F]+$/.test(s)) return 'hex';
if (/^[A-Za-z0-9+/]+={0,2}$/.test(s)) return 'base64';
return 'unknown';
}
/** Identify candidate hash types. Always returns HashInfo; never throws. */
export function identifyHash(input: string): HashInfo {
const cleaned = (input || '').trim();
const charset = detectCharset(cleaned);
const length = cleaned.length;
let candidates: HashMatch[] = [];
if (charset === 'bcrypt') {
candidates = [{ name: 'bcrypt', bitLength: 184 }];
} else if (charset === 'argon2') {
candidates = [{ name: 'Argon2', bitLength: 0 }];
} else if (charset === 'hex') {
const names = HEX_BY_LENGTH[length] ?? [];
candidates = names.map((name) => ({ name, bitLength: length * 4 }));
} else if (charset === 'base64') {
const names = BASE64_BY_LENGTH[length] ?? [];
candidates = names.map((name) => ({ name, bitLength: Math.round((length * 6) / 8) * 8 }));
}
return { input: input ?? '', cleaned, length, charset, candidates };
}
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 →