Standalone check-digit algorithms (Luhn, Verhoeff, ISO 7064), usable directly when you need the primitive rather than a typed identifier validator.
Each algorithm offers a *-valid? predicate over a complete string (payload +
trailing check character) and, where meaningful, a *-check-digit /
*-check calculator that returns the check character for a bare payload.
(luhn-valid? "79927398713") ;=> true
(luhn-check-digit "7992739871") ;=> "3"
(iso7064-mod11-2-check "000000021825009") ;=> "7" (ORCID)
Standalone check-digit algorithms (Luhn, Verhoeff, ISO 7064), usable directly
when you need the primitive rather than a typed identifier validator.
Each algorithm offers a `*-valid?` predicate over a complete string (payload +
trailing check character) and, where meaningful, a `*-check-digit` /
`*-check` calculator that returns the check character for a bare payload.
(luhn-valid? "79927398713") ;=> true
(luhn-check-digit "7992739871") ;=> "3"
(iso7064-mod11-2-check "000000021825009") ;=> "7" (ORCID)Unified validation, parsing, and formatting of standard identifier numbers.
One API over several identifier types - credit cards, IBAN/BIC, ISBN, ISSN, ISIN, US bank routing (ABA), IMEI, and the raw Luhn check - dispatched on a type keyword. Idiomatic Clojure data in and out; an idiomatic facade over the maintained Apache Commons Validator and iban4j engines (it does not reinvent the algorithms).
(valid? :iban "GB82 WEST 1234 5698 7654 32") ;=> true
(parse :credit-card "4111111111111111") ;=> {:valid? true :network :visa}
(format :iban "GB82WEST12345698765432") ;=> "GB82 WEST 1234 5698 7654 32"
(detect "4111111111111111") ;=> [:credit-card :luhn]
valid?/parse/format throw only on an unknown identifier type (a caller
bug); bad input data never throws - valid? returns false, parse returns
{:valid? false}, format returns nil.
Unified validation, parsing, and formatting of standard identifier numbers.
One API over several identifier types - credit cards, IBAN/BIC, ISBN, ISSN,
ISIN, US bank routing (ABA), IMEI, and the raw Luhn check - dispatched on a
type keyword. Idiomatic Clojure data in and out; an idiomatic facade over the
maintained Apache Commons Validator and iban4j engines (it does not reinvent
the algorithms).
(valid? :iban "GB82 WEST 1234 5698 7654 32") ;=> true
(parse :credit-card "4111111111111111") ;=> {:valid? true :network :visa}
(format :iban "GB82WEST12345698765432") ;=> "GB82 WEST 1234 5698 7654 32"
(detect "4111111111111111") ;=> [:credit-card :luhn]
`valid?`/`parse`/`format` throw only on an unknown identifier type (a caller
bug); bad input data never throws - `valid?` returns false, `parse` returns
{:valid? false}, `format` returns nil.Parsing of GS1-128 (formerly UCC/EAN-128) element strings - the Application Identifier (AI) encoding used on logistics and retail barcodes.
parse accepts either the human-readable parenthesized form or the raw scanned
form (variable-length fields terminated by FNC1 / ASCII group-separator 0x1D),
and returns a vector of segment maps in order:
(parse "(01)09521234543213(15)170331(10)ABC123")
;=> [{:ai "01" :label "GTIN" :value "09521234543213"}
; {:ai "15" :label "BEST BEFORE" :value "170331"}
; {:ai "10" :label "BATCH/LOT" :value "ABC123"}]
Weight/measure and amount AIs carry an implied decimal place (the AI's last
digit); those segments also report :decimals and a numeric :decimal-value.
Parsing of GS1-128 (formerly UCC/EAN-128) element strings - the Application
Identifier (AI) encoding used on logistics and retail barcodes.
`parse` accepts either the human-readable parenthesized form or the raw scanned
form (variable-length fields terminated by FNC1 / ASCII group-separator 0x1D),
and returns a vector of segment maps in order:
(parse "(01)09521234543213(15)170331(10)ABC123")
;=> [{:ai "01" :label "GTIN" :value "09521234543213"}
; {:ai "15" :label "BEST BEFORE" :value "170331"}
; {:ai "10" :label "BATCH/LOT" :value "ABC123"}]
Weight/measure and amount AIs carry an implied decimal place (the AI's last
digit); those segments also report `:decimals` and a numeric `:decimal-value`.Online EU VAT validation against the official VIES service
(https://ec.europa.eu/taxation_customs/vies/). This is the one capability in
the library that performs network I/O - it is kept in its own namespace so
stdnum.core stays pure and dependency-light. check confirms a VAT number
actually exists in the member-state registry (and returns the trader name /
address where the state discloses them), which a checksum cannot do.
(require '[stdnum.vies :as vies])
(vies/check "DE136695976")
;=> {:valid? true, :country "DE", :vat-number "136695976", :name "...", ...}
Requires JDK 11+ (uses java.net.http). On any network/service failure check
returns {:error <message>} rather than throwing.
Online EU VAT validation against the official VIES service
(https://ec.europa.eu/taxation_customs/vies/). This is the one capability in
the library that performs network I/O - it is kept in its own namespace so
`stdnum.core` stays pure and dependency-light. `check` confirms a VAT number
actually *exists* in the member-state registry (and returns the trader name /
address where the state discloses them), which a checksum cannot do.
(require '[stdnum.vies :as vies])
(vies/check "DE136695976")
;=> {:valid? true, :country "DE", :vat-number "136695976", :name "...", ...}
Requires JDK 11+ (uses java.net.http). On any network/service failure `check`
returns `{:error <message>}` rather than throwing.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |