Skip to content

Instantly share code, notes, and snippets.

@smolak
Created February 9, 2020 22:26
Show Gist options
  • Save smolak/06c706d8c249df753397b01e5939ffb6 to your computer and use it in GitHub Desktop.
Save smolak/06c706d8c249df753397b01e5939ffb6 to your computer and use it in GitHub Desktop.
ISBN 10 and 13 verifier
(ns isbn-verifier)
(defn- digits
"Splits ISBN 10 string into collection of digits"
[col]
(keep #(cond
(Character/isDigit %) (Character/getNumericValue %)
(= \X %) 10)
col))
(defn- isbn10-checksum
"Calculates ISBN 10 checksum"
[digits]
(->> digits
(map * (range 10 1 -1))
(apply +)
(#(- 11 (mod % 11)))))
(defn- isbn13-checksum
"Calculates ISBN 13 checksum"
[digits]
(->> digits
(map * (flatten (repeat 6 '(1 3))))
(apply +)
(#(- 10 (mod % 10)))))
(defn- isbn10?
"Validates ISBN 10 number"
[string]
(let [checksum? #(= (isbn10-checksum %) (last %))]
(and (not= nil (re-matches #"\d[-]?\d{3}[-]?\d{5}[-]?[\d|X]" string))
(checksum? (digits string)))))
(defn- isbn13?
"Validates ISBN 13 number"
[string]
(let [checksum? #(= (isbn13-checksum %) (last %))]
(and (not= nil (re-matches #"978[-]?\d[-]?\d{3}[-]?\d{5}[-]?[\d|X]" string))
(checksum? (digits string)))))
(defn- isbn10->13
"Converts ISBN 10 string to ISBN 13 one"
[isbn10]
(str "978-" isbn10))
(defn isbn?
"Validates ISBN number"
[isbn]
(and (isbn10? isbn)
(isbn13? (isbn10->13 isbn))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment