Guide

CLI

The hashes command. Hash and HMAC and verify from a shell or stdin with the digest alone on stdout

Install or run once

shell
npx @agntn/hashes sha256 "hello world"
pnpm add -g @agntn/hashes   # then plain `hashes`

Commands

CommandWhat it doesExample
hashDigest of text, or of stdin with -hashes hash blake3 - < file.bin
hmacKeyed digesthashes hmac sha256 message secret
verifyCompare with an expected digest, exit 1 if nothashes verify md5 hello 5d41402abc4b2a76b9719d911017c592
algorithmsThe list, -f keeps one familyhashes algorithms -f password
infoOne algorithm with its optionshashes info pbkdf2
mcpThe MCP server on stdiohashes mcp

hash is the default, so the first word can be the algorithm. hashes md5 hello and hashes hash md5 hello are the same call.

Stdout is the digest

Only the digest goes to stdout, so it pipes and it lands in a variable without trimming:

shell
digest=$(hashes sha256 abc)
echo -n abc | hashes sha256 -
# ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

A KDF's salt and cost go to stderr, since the digest is useless without them. -e binary writes the raw bytes, for xxd or the next tool in the pipe. Stdin is read byte for byte, so a file hashes the same as sha256sum would hash it.

Flags

shell
hashes hash --help

-e, --encoding picks the output: hex (default), base64, base64url, binary. --input-encoding picks how the input is read: utf8 (default), or hex and base64 for the bytes they spell. --key-encoding does the same for the HMAC key.

shell
hashes hash160 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 --input-encoding hex
# 751e76e8199196d454941c45d1b3a323f1433bd6

Without the flag that same line hashes 66 characters of text, which is a valid digest of the wrong thing. The flag also applies to stdin.

The rest of the flags come from what the algorithms declare in info().options: --salt, --N, --r, --p, --keyLength, --iterations, --digest for the KDFs, --seed for xxHash. The help text names which algorithms take each one. A flag the algorithm doesn't declare is an error, not a digest computed without it:

shell
hashes xxhash abc --seed 1
# bea9ca8199328908
hashes sha256 abc --seed 1
# Invalid option seed=1: sha256 takes no parameters

Exit codes

0 for a digest, and for verify a match. 1 for a mismatch, and for any error in the input: an unknown name, a bad option, a missing salt. The error is one line on stderr, with no stack trace:

shell
hashes sha265 abc
# Unknown algorithm: sha265. Available: sha256, sha384, sha512, ...

A pipe that closes early (| head -1) ends the process quietly instead of throwing EPIPE at you. Colours only show up when both stdout and stderr are terminals that want them, and NO_COLOR is respected.