| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Algorithm::CheckDigits::MXX_003; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 1 |  |  | 1 |  | 17 | use 5.006; | 
|  | 1 |  |  |  |  | 3 |  | 
| 4 | 1 |  |  | 1 |  | 5 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 20 |  | 
| 5 | 1 |  |  | 1 |  | 5 | use warnings; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 22 |  | 
| 6 | 1 |  |  | 1 |  | 4 | use integer; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 4 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 1 |  |  | 1 |  | 20 | use version; our $VERSION = qv('v1.3.6'); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | our @ISA = qw(Algorithm::CheckDigits); | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | my $perm = [ | 
| 13 |  |  |  |  |  |  | [ 1, 5, 7, 6, 2, 8, 3, 0, 9, 4, ], | 
| 14 |  |  |  |  |  |  | [ 5, 8, 0, 3, 7, 9, 6, 1, 4, 2, ], | 
| 15 |  |  |  |  |  |  | [ 8, 9, 1, 6, 0, 4, 3, 5, 2, 7, ], | 
| 16 |  |  |  |  |  |  | [ 9, 4, 5, 3, 1, 2, 6, 8, 7, 0, ], | 
| 17 |  |  |  |  |  |  | [ 4, 2, 8, 6, 5, 7, 3, 9, 0, 1, ], | 
| 18 |  |  |  |  |  |  | [ 2, 7, 9, 3, 8, 0, 6, 4, 1, 5, ], | 
| 19 |  |  |  |  |  |  | [ 7, 0, 4, 6, 9, 1, 3, 2, 5, 8, ], | 
| 20 |  |  |  |  |  |  | [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ], | 
| 21 |  |  |  |  |  |  | [ 1, 5, 7, 6, 2, 8, 3, 0, 9, 4, ], | 
| 22 |  |  |  |  |  |  | [ 5, 8, 0, 3, 7, 9, 6, 1, 4, 2, ], | 
| 23 |  |  |  |  |  |  | [ 8, 9, 1, 6, 0, 4, 3, 5, 2, 7, ], | 
| 24 |  |  |  |  |  |  | ]; | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | my $dieder = [ | 
| 27 |  |  |  |  |  |  | [ 0, 1, 2, 3, 4,   5, 6, 7, 8, 9, ], | 
| 28 |  |  |  |  |  |  | [ 1, 2, 3, 4, 0,   6, 7, 8, 9, 5, ], | 
| 29 |  |  |  |  |  |  | [ 2, 3, 4, 0, 1,   7, 8, 9, 5, 6, ], | 
| 30 |  |  |  |  |  |  | [ 3, 4, 0, 1, 2,   8, 9, 5, 6, 7, ], | 
| 31 |  |  |  |  |  |  | [ 4, 0, 1, 2, 3,   9, 5, 6, 7, 8, ], | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | [ 5, 9, 8, 7, 6,   0, 4, 3, 2, 1, ], | 
| 34 |  |  |  |  |  |  | [ 6, 5, 9, 8, 7,   1, 0, 4, 3, 2, ], | 
| 35 |  |  |  |  |  |  | [ 7, 6, 5, 6, 8,   2, 1, 0, 4, 3, ], | 
| 36 |  |  |  |  |  |  | [ 8, 7, 6, 5, 9,   3, 2, 1, 0, 4, ], | 
| 37 |  |  |  |  |  |  | [ 9, 8, 7, 6, 5,   4, 3, 2, 1, 0, ], | 
| 38 |  |  |  |  |  |  | ]; | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | sub new { | 
| 41 | 1 |  |  | 1 | 0 | 3 | my $proto = shift; | 
| 42 | 1 |  |  |  |  | 2 | my $type  = shift; | 
| 43 | 1 |  | 33 |  |  | 6 | my $class = ref($proto) || $proto; | 
| 44 | 1 |  |  |  |  | 3 | my $self  = bless({}, $class); | 
| 45 | 1 |  |  |  |  | 8 | $self->{type} = lc($type); | 
| 46 | 1 |  |  |  |  | 5 | return $self; | 
| 47 |  |  |  |  |  |  | } # new() | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | sub is_valid { | 
| 50 | 2 |  |  | 2 | 1 | 8 | my ($self,$number) = @_; | 
| 51 | 2 | 50 |  |  |  | 11 | if ($number =~ /^([ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ])(\d)$/i) { | 
| 52 | 2 | 100 |  |  |  | 9 | return 1 if ($2 == $self->_compute_checkdigit(uc($1))); | 
| 53 |  |  |  |  |  |  | } | 
| 54 | 1 |  |  |  |  | 6 | return '' | 
| 55 |  |  |  |  |  |  | } # is_valid() | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | sub complete { | 
| 58 | 1 |  |  | 1 | 1 | 96 | my ($self,$number) = @_; | 
| 59 | 1 | 50 |  |  |  | 7 | if ($number =~ /^[ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ]$/i) { | 
| 60 | 1 |  |  |  |  | 4 | return $number .  $self->_compute_checkdigit(uc($number)); | 
| 61 |  |  |  |  |  |  | } | 
| 62 | 0 |  |  |  |  | 0 | return ''; | 
| 63 |  |  |  |  |  |  | } # complete() | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | sub basenumber { | 
| 66 | 1 |  |  | 1 | 1 | 3 | my ($self,$number) = @_; | 
| 67 | 1 | 50 |  |  |  | 6 | if ($number =~ /^([ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ])(\d)$/i) { | 
| 68 | 1 | 50 |  |  |  | 5 | return $1 if ($2 == $self->_compute_checkdigit(uc($1))); | 
| 69 |  |  |  |  |  |  | } | 
| 70 | 0 |  |  |  |  | 0 | return ''; | 
| 71 |  |  |  |  |  |  | } # basenumber() | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | sub checkdigit { | 
| 74 | 1 |  |  | 1 | 1 | 3 | my ($self,$number) = @_; | 
| 75 | 1 | 50 |  |  |  | 6 | if ($number =~ /^([ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ])(\d)$/i) { | 
| 76 | 1 | 50 |  |  |  | 4 | return $2 if ($2 == $self->_compute_checkdigit(uc($1))); | 
| 77 |  |  |  |  |  |  | } | 
| 78 | 0 |  |  |  |  | 0 | return ''; | 
| 79 |  |  |  |  |  |  | } # checkdigit() | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | sub _compute_checkdigit { | 
| 82 | 5 |  |  | 5 |  | 10 | my $self   = shift; | 
| 83 | 5 |  |  |  |  | 7 | my $number = shift; | 
| 84 |  |  |  |  |  |  |  | 
| 85 | 5 |  |  |  |  | 10 | $number =~ tr/ADGKLNSUYZ/0-9/; | 
| 86 | 5 |  |  |  |  | 20 | my @digits = split(//,$number); | 
| 87 | 5 |  |  |  |  | 13 | my $p0 = $perm->[0]->[$digits[0]]; | 
| 88 | 5 |  |  |  |  | 7 | my $rd = $p0; | 
| 89 |  |  |  |  |  |  |  | 
| 90 | 5 |  |  |  |  | 16 | for (my $i = 1; $i <= $#digits; $i++) { | 
| 91 | 45 |  |  |  |  | 72 | my $pi = $perm->[$i % 8]->[$digits[$i]]; | 
| 92 | 45 |  |  |  |  | 90 | $rd = $dieder->[$rd]->[$pi]; | 
| 93 |  |  |  |  |  |  | } | 
| 94 | 5 |  |  |  |  | 12 | for (my $j = 0; $j <= 9; $j++) { | 
| 95 | 10 | 100 |  |  |  | 48 | return $j unless($dieder->[$rd]->[$j]); | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  |  | 
| 98 | 0 |  |  |  |  |  | return -1; | 
| 99 |  |  |  |  |  |  | } # _compute_checkdigit() | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | # Preloaded methods go here. | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | 1; | 
| 104 |  |  |  |  |  |  | __END__ |