Last active
August 29, 2015 14:07
-
-
Save bhanafee/6632948f44de89883759 to your computer and use it in GitHub Desktop.
Compute Luhn checksum for credit card or check digit for ABA Routing Transit Number RTN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Checksum { | |
val seed: Seq[Int] | |
def op(c: Int, x: Int): Int | |
def coefficients: Stream[Int] = Stream.continually(seed).flatten | |
/** Computes the checksum for a sequence of Ints beginning with the least significant. */ | |
def compute(xs: Seq[Int]): Int = (10 - xs.zip(coefficients).map(x => op(x._1, x._2)).sum % 10) % 10 | |
/** Computes the check digit for a string of digits. */ | |
def compute(x: String): Char = compute(Checksum.digits(x)).toString.head | |
/** Validates that the first Int in a squence is the correct checksum for the remaining valus. */ | |
def validate(xs: Seq[Int]): Boolean = xs.head == compute(xs.tail) | |
/** Validates that the string of digits has the correct checksum. */ | |
def validate(x: String): Boolean = validate(Checksum.digits(x)) | |
} | |
object Checksum { | |
def digits(s: String): Seq[Int] = s.filter('0' to '9' contains _).map(_.asDigit).reverse | |
} | |
object RTN extends Checksum { | |
val seed = Seq(7, 3, 1) | |
def op(c: Int, x: Int): Int = c * x | |
} | |
object Luhn extends Checksum{ | |
val seed = Seq(2, 1) | |
def op(c: Int, x: Int): Int = { | |
val p = c * x | |
if (p < 10) p else p - 9 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment