Algorithm-LUHN
view release on metacpan or search on metacpan
lib/Algorithm/LUHN.pm view on Meta::CPAN
package Algorithm::LUHN;
$Algorithm::LUHN::VERSION = '1.02';
use 5.006;
use strict;
use warnings;
use Exporter;
our @ISA = qw/Exporter/;
our @EXPORT = qw//;
our @EXPORT_OK = qw/check_digit is_valid valid_chars/;
our $ERROR;
# The hash of valid characters.
my %map = map { $_ => $_ } 0..9;
=pod
=head1 NAME
Algorithm::LUHN - Calculate the Modulus 10 Double Add Double checksum
=head1 SYNOPSIS
use Algorithm::LUHN qw/check_digit is_valid/;
$c = check_digit("43881234567");
print "It works\n" if is_valid("43881234567$c");
$c = check_digit("A2C4E6G8"); # this will cause an error
print "Valid LUHN characters are:\n";
my %vc = Algorithm::LUHN::valid_chars();
for (sort keys %vc) {
print "$_ => $vc{$_}\n";
}
Algorithm::LUHN::valid_chars(map {$_ => ord($_)-ord('A')+10} A..Z);
$c = check_digit("A2C4E6G8");
print "It worked again\n" if is_valid("A2C4E6G8$c");
=head1 DESCRIPTION
This module calculates the Modulus 10 Double Add Double checksum, also known as
the LUHN Formula. This algorithm is used to verify credit card numbers and
Standard & Poor's security identifiers such as CUSIP's and CSIN's.
You can find plenty of information about the algorithm by searching the web for
"modulus 10 double add double".
=head1 FUNCTION
=over 4
=cut
=item is_valid CHECKSUMMED_NUM
This function takes a credit-card number and returns true if
the number passes the LUHN check.
Ie it returns true if the final character of CHECKSUMMED_NUM is the
correct checksum for the rest of the number and false if not. Obviously the
final character does not factor into the checksum calculation. False will also
be returned if NUM contains in an invalid character as defined by
valid_chars(). If NUM is not valid, $Algorithm::LUHN::ERROR will contain the
reason.
This function is equivalent to
substr $N,length($N)-1 eq check_digit(substr $N,0,length($N)-1)
For example, C<4242 4242 4242 4242> is a valid Visa card number,
that is provided for test purposes. The final digit is '2',
which is the right check digit. If you change it to a '3', it's not
a valid card number. Ie:
is_valid('4242424242424242'); # true
is_valid('4242424242424243'); # false
=cut
sub is_valid {
my $N = shift;
my $c = check_digit(substr($N, 0,length($N)-1));
if (defined $c) {
if (substr($N,length($N)-1, 1) eq $c) {
return 1;
} else {
$ERROR = "Check digit incorrect. Expected $c";
( run in 4.287 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )