様々な識別番号の認証に使われている単純なチェックサム方式。
たとえば、クレジットカード番号にもこの方式が使われている。
詳細は wikipeida参照。
このLuhnアルゴリズムのさまざな言語での実装が、
Implementation in 88 languages on the Rosetta Code project
に載っているので、そちらを見ていただいても構わない。
で、先日ISBNのコードを書いている途中、
たまたまLuhnアルゴリズムに出くわしたので、
「関数の循環リスト」を使った、schemeでの実装を書いてみた。
なお、入力は文字列として受け取る。
(define (check-luhn num-string)
(define luhn-digit
(circular-list (lambda (x) x)
(lambda (x) (vector-ref #(0 2 4 6 8 1 3 5 7 9) x))))
(zero? (remainder (fold + 0 (map (lambda (f x) (f x))
luhn-digit
(reverse (map digit->integer (string->list num-string)))))
10)))
;; (check-luhn "1234567812345678")
なんというか、schemeならではの素敵なコードになったと思うので、
ここに記録しておく。
以上