Wednesday, June 26, 2013

Simple Credit Card Validator

Validating credit cards numbers is a fairly simple job, and there are no short supply of algorithms out there you can easily download to do it. That being said, it is a perfect algorithm to write in Haxe for the following reasons:
  • Speed isn't super critical
  • It doesn't involve the system in any way
  • You can use the same code across PHP, JS, Java, C++, C#, Actionscript etc.
  • The same code would be useful in all contexts.

Algorithm

The algorithm realized here is the Luhn algorithm. You can do the formal proofs with some discrete math, or trust the Wikipedia Article that it is useful because:
  • It detects any one digit error e.g. 1235 instead of 1234
  • It detects any one transposition e.g. 1324 instead of 1234
Both errors are exceedingly common for human typists.
(Note that the ISBN10 algorithm holds some of these same properties.)

The Code

/**
A simple credit card validator that just runs the luhn algorithm against the
given number. It doesn't even check to see if the string is long enough!
**/
class Validator
{
/**
Call this function with a string of digits that represent a credit card
number.
**/
public static function validate(cardNumber : String) : Bool
{
return (luhn(cardNumber) == 0);
}

private static function luhn(numericString : String) : Int
{
var output = stringToDigitArray(numericString);
var sum : Int = 0;

var isEven : Bool = true;
for( i in output.iterator())
{
if(isEven)
{
sum += sumOfDigits(i * 2);
}
else
{
sum += i;
}

isEven = !isEven; // Invert sign for next iteration
}

return sum % 10;
}

private static function stringToDigitArray(numericString : String) : Array<Int>
{
var output = new Array<Int>();
for( i in 0...numericString.length)
{
output.push(Std.parseInt(numericString.charAt(i)));
}

return output;
}

private static function sumOfDigits(number : Int) : Int
{
var sum : Int = 0;

while(number != 0)
{
sum += number % Std.int(10);
number = Std.int(number / Std.int(10));
}

sum += number;

return sum;
}

/* Examples */
public static function main() : Void
{
// False
trace(Validator.validate("1111111111111111"));

// All true below this point
trace(Validator.validate("4271058012370682"));
trace(Validator.validate("4052047247466840"));
trace(Validator.validate("4250112315345738"));
trace(Validator.validate("4302220036446780"));
trace(Validator.validate("4271382676044056"));
trace(Validator.validate("4027883785016825"));
trace(Validator.validate("4125875428334483"));
trace(Validator.validate("4231380166327600"));
trace(Validator.validate("4820020713741757"));
trace(Validator.validate("4013112216053363"));
}
}

No comments:

Post a Comment