Verhoeff algorithm: Difference between revisions

(Added C solution)
Line 548:
Check digit validation was successful for 1234567890120.
Check digit validation failed for 1234567890129.</pre>
 
=={{header|Perl}}==
<lang perl>#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Verhoeff_algorithm
use warnings;
 
my @inv = qw(0 4 3 2 1 5 6 7 8 9);
 
my @d = map [ split ], split /\n/, <<END;
0 1 2 3 4 5 6 7 8 9
1 2 3 4 0 6 7 8 9 5
2 3 4 0 1 7 8 9 5 6
3 4 0 1 2 8 9 5 6 7
4 0 1 2 3 9 5 6 7 8
5 9 8 7 6 0 4 3 2 1
6 5 9 8 7 1 0 4 3 2
7 6 5 9 8 2 1 0 4 3
8 7 6 5 9 3 2 1 0 4
9 8 7 6 5 4 3 2 1 0
END
 
my @p = map [ split ], split /\n/, <<END;
0 1 2 3 4 5 6 7 8 9
1 5 7 6 2 8 3 0 9 4
5 8 0 3 7 9 6 1 4 2
8 9 1 6 0 4 3 5 2 7
9 4 5 3 1 2 6 8 7 0
4 2 8 6 5 7 3 9 0 1
2 7 9 3 8 0 6 4 1 5
7 0 4 6 9 1 3 2 5 8
END
 
my $debug;
 
sub generate
{
local $_ = shift() . 0;
my $c = my $i = 0;
my ($n, $p);
$debug and print "i ni d(c,p(i%8,ni)) c\n";
while( length )
{
$c = $d[ $c ][ $p = $p[ $i % 8 ][ $n = chop ] ];
$debug and printf "%d%3d%7d%10d\n", $i, $n, $p, $c;
$i++;
}
return $inv[ $c ];
}
 
sub validate { shift =~ /(\d+)(\d)/ and $2 == generate($1) }
 
for ( 236, 12345, 123456789012 )
{
print "testing $_\n";
$debug = length() < 6;
my $checkdigit = generate($_);
print "check digit for $_ is $checkdigit\n";
$debug = 0;
for my $cd ( $checkdigit, 9 )
{
print "$_$cd is ", validate($_ . $cd) ? '' : 'not ', "valid\n";
}
print "\n";
}</lang>
{{out}}
<pre>
testing 236
i ni d(c,p(i%8,ni)) c
0 0 0 0
1 6 3 3
2 3 3 1
3 2 1 2
check digit for 236 is 3
2363 is valid
2369 is not valid
 
testing 12345
i ni d(c,p(i%8,ni)) c
0 0 0 0
1 5 8 8
2 4 7 1
3 3 6 7
4 2 5 2
5 1 2 4
check digit for 12345 is 1
123451 is valid
123459 is not valid
 
testing 123456789012
check digit for 123456789012 is 0
1234567890120 is valid
1234567890129 is not valid
 
</pre>
 
=={{header|Phix}}==
Anonymous user