2019年2月11日月曜日

循環リストの応用例その2(Luhnアルゴリズム)

Luhnアルゴリズム(Luhn algorithm)は、
様々な識別番号の認証に使われている単純なチェックサム方式。
たとえば、クレジットカード番号にもこの方式が使われている。
詳細は 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ならではの素敵なコードになったと思うので、
ここに記録しておく。

以上