Functional Weave
Code in TypeScript

validation.luhn@1.0.0

README.md

1,424 bytes · view raw

# validation.luhn

Luhn is a transcription check, not an authorisation. A number that passes is
well formed: a single mistyped digit, and every adjacent transposition except
0<->9, would have failed. A number that passes may still be unissued, closed,
stolen or empty. Only the card scheme or issuer can answer that, so never show a
user "card valid" because this returned true - the honest wording is "that
doesn't look like a complete card number" on false, and nothing at all on true.

Accepted input: ASCII digits, optionally separated by ASCII spaces or hyphens
anywhere (including leading and trailing), because cards are printed and pasted
in four-digit groups. Any other character, including underscores, dots,
non-breaking spaces and non-ASCII digits, makes the whole value invalid rather
than being skipped.

At least two digits are required. A single "0" satisfies the arithmetic, and
accepting it would turn this into a rubber stamp for a stray keystroke.

This capability deliberately does not check length or issuer prefix. A 16-digit
Visa, a 15-digit Amex and a 15-digit IMEI all use the same checksum, and baking
card-brand rules in here would make it useless for everything else. Pair it with
a separate brand check if you need one.

Validators answer rather than throw: an unparseable value is not an exceptional
condition, it is the answer "no". A non-string argument is therefore false, not
a TypeError.