Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,67 @@
BEGIN # The Verhoeff algorithm - translated from the Wren sample via FreeBASIC #
[,]INT d = ( ( 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 )
);
[ ]INT inv = ( 0, 4, 3, 2, 1, 5, 6, 7, 8, 9 );
[,]INT p = ( ( 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 )
);
PROC verhoeff algorithm = ( STRING s in, BOOL validate, table )INT:
BEGIN
IF table THEN
print( ( IF validate THEN "Validation" ELSE "Check digit" FI ) );
print( ( " calculations for '", s in, "':", newline ) );
print( ( " i ni p[i,ni] c", newline, " ------------------", newline ) )
FI;
STRING s = IF validate THEN s in ELSE s in + "0" FI;
INT c := 0;
INT le = UPB s;
FOR k FROM le BY -1 TO LWB s DO
INT nidx = ABS s[ k ] - 48;
INT pidx = p[ 1 + ( le - k ) MOD 8, 1 + nidx ];
c := d[ c + 1, pidx + 1 ];
IF table
THEN print( ( " ", whole( le - k, -2 ), " ", whole( nidx, 0 ), " ", whole( pidx, 0 ) ) );
print( ( " ", whole( c, 0 ), newline ) )
FI
OD;
IF table AND NOT validate
THEN print( ( " inv[", whole( c, 0 ), "] = ", whole( inv[ c + 1 ], 0 ), newline ) )
FI;
IF NOT validate THEN inv[ c + 1 ] ELSE c FI
END # verhoeff algorithm # ;
PROC verhoeff validation = ( STRING s, BOOL table )BOOL: verhoeff algorithm( s, TRUE, table ) = 0;
PROC verhoeff check digit = ( STRING s, BOOL table )INT: verhoeff algorithm( s, FALSE, table );
BEGIN # test cases #
MODE TCASE = STRUCT( STRING s, BOOL table );
[]TCASE sts = ( ( "236", TRUE ), ( "12345", TRUE ), ( "123456789012", FALSE ) );
FOR i FROM LWB sts TO UPB sts DO
STRING s = s OF sts[ i ];
INT c = verhoeff check digit( s, table OF sts[ i ] );
print( ( "The check digit for '", s, "' is '", whole( c, 0 ), "'", newline ) );
[]STRING stc = ( s + REPR ( c + ABS "0" ), s + "9" );
FOR j FROM LWB stc TO UPB stc DO
BOOL v = verhoeff validation( stc[ j ], table OF sts[ i ] );
print( ( "Validation for '", stc[ j ], "' -> " ) );
print( ( IF v THEN "correct" ELSE "incorrect" FI, ".", newline ) )
OD;
print( ( newline, newline ) )
OD
END
END

View file

@ -0,0 +1,45 @@
d[][] = [ [ 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 ] ]
inv[] = [ 0 4 3 2 1 5 6 7 8 9 ]
p[][] = [ [ 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 ] ]
#
func verhoeff s$ validate verbose .
if verbose = 1
t$ = "Check digit"
if validate = 1 : t$ = "Validation"
print t$ & " calculations for '" & s$ & "'\n"
print " i nᵢ p[i,nᵢ] c"
print "------------------"
.
s$[] = strchars s$
lng = len s$[]
if validate = 1 : lng -= 1
for i = lng downto 0
ni = 0
if i < lng or validate = 1 : ni = strcode s$[i + 1] - 48
if ni < 0 or ni > 9 : print "error"
pii = p[(lng - i) mod 8 + 1][ni + 1]
c = d[c + 1][pii + 1]
if verbose = 1 : print " " & lng - i & " " & ni & " " & pii & " " & c
.
if verbose = 1 and validate = 0 : print "\ninv[" & c & "] = " & inv[c + 1]
if validate = 1 : return if c = 0
return inv[c + 1]
.
ss$[] = [ "236" "12345" "123456789012" ]
for i to 3
s$ = ss$[i]
verbose = if i <= 2
c = verhoeff s$ 0 verbose
print "\nThe check digit for '" & s$ & "' is '" & c & "'."
sc$ = s$
for j to 2
if j = 1
sc$ &= c
else
sc$ &= "9"
.
h$ = "incorrect"
if verhoeff sc$ 1 verbose = 1 : h$ = "correct"
print "\nThe validation for '" & sc$ & "' is " & h$ & "."
.
.

View file

@ -0,0 +1,117 @@
module verhoeff_mod
implicit none
!----------------------------------------------------------------
! Zero-based Verhoeff tables d, inv, p
!----------------------------------------------------------------
integer, parameter :: d1 = 10, d2 = 10
integer, parameter :: d(0:d1 - 1, 0:d2 - 1) = reshape([ &
! 10 rows of 10 ints each exactly as in VB,
! listed row-major so we use ORDER=[2,1] below
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 ], shape=[d1, d2], order=[2, 1])
integer, parameter :: inv(0:d1 - 1) = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
integer, parameter :: r = 8, c = 10
integer, parameter :: p(0:r - 1, 0:c - 1) = reshape([ &
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 ], shape=[r, c], order=[2, 1])
contains
!----------------------------------------------------------------
! verhoeff()
! s : input digit-string
! validate : .TRUE. for check, .FALSE. to compute digit
! table : .TRUE. to dump tables, .FALSE. to skip
! returns
! if(validate) 1=>valid, 0=>invalid
! if(.not.validate) the computed check digit (09)
!----------------------------------------------------------------
function verhoeff(s, validate, table) result(res)
implicit none
character(len=*), intent(in) :: s
logical, intent(in) :: validate, table
integer :: res
integer :: c, lens, k, digit, pi
character(len=:), allocatable :: str
res = 0
! Append '0' when generating the check digit
if (.not.validate) then
str = trim(s) // '0'
else
str = trim(s)
end if
lens = len_trim(str)
c = 0
! Main Verhoeff loop: right-to-left over str
do k = lens, 1, -1
digit = ichar(str(k:k)) - ichar('0')
pi = p(mod(lens - k, size(p, 1)), digit)
c = d(c, pi)
if (table) then
write(*, '(I2,1X,I2,2X,I2,2X,I2)') lens - k, digit, pi, c
end if
end do
if (.not.validate) then
! computing check digit
res = inv(c)
else
! validating: success only if c==0
res = merge(1, 0, c == 0)
end if
end function verhoeff
end module verhoeff_mod
program test_verhoeff
use verhoeff_mod
implicit none
character(len=20), parameter :: inputs(3) = [character(len=20) :: '236', '12345', '123456789012' ]
logical, parameter :: showtable(3) = [ .true., .true., .false. ]
integer :: i, chk, ok
character(len=:), allocatable :: withchk, with9
do i = 1, 3
! Compute the check digit
chk = verhoeff(inputs(i), .false., showtable(i))
write(*, '(3A,I1)') 'Check digit for "', trim(inputs(i)), '" is ', chk
! Test two variants: one with the computed digit, one with '9'
withchk = trim(inputs(i)) // achar(ichar('0') + chk)
with9 = trim(inputs(i)) // '9'
ok = verhoeff(withchk, .true., showtable(i))
write(*, '(4A)') 'Validation for "', trim(withchk), '" : ', &
merge(' correct ', 'incorrect', ok == 1)
ok = verhoeff(with9, .true., showtable(i))
write(*, '(4A)') 'Validation for "', trim(with9), '" : ', &
merge(' correct ', 'incorrect', ok == 1)
write(*, *)
end do
end program test_verhoeff

View file

@ -0,0 +1,139 @@
MODULE VerhoeffAlgorithm; (* translated from the Wren sample via FreeBASIC & Algol 68 *)
IMPORT Out, Strings;
VAR d : ARRAY 10, 10 OF INTEGER;
inv : ARRAY 10 OF INTEGER;
p : ARRAY 8, 10 OF INTEGER;
(* initialises an array of 10 INTEGERs *)
PROCEDURE set10( VAR a : ARRAY OF INTEGER
; v0, v1, v2, v3, v4, v5, v6, v7, v8, v9 : INTEGER
);
BEGIN
a[ 0 ] := v0; a[ 1 ] := v1; a[ 2 ] := v2; a[ 3 ] := v3; a[ 4 ] := v4;
a[ 5 ] := v5; a[ 6 ] := v6; a[ 7 ] := v7; a[ 8 ] := v8; a[ 9 ] := v9
END set10;
PROCEDURE init; (* initialises the tables for the Verhoeff algorithm *)
BEGIN
set10( d[ 0 ], 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 );
set10( d[ 1 ], 1, 2, 3, 4, 0, 6, 7, 8, 9, 5 );
set10( d[ 2 ], 2, 3, 4, 0, 1, 7, 8, 9, 5, 6 );
set10( d[ 3 ], 3, 4, 0, 1, 2, 8, 9, 5, 6, 7 );
set10( d[ 4 ], 4, 0, 1, 2, 3, 9, 5, 6, 7, 8 );
set10( d[ 5 ], 5, 9, 8, 7, 6, 0, 4, 3, 2, 1 );
set10( d[ 6 ], 6, 5, 9, 8, 7, 1, 0, 4, 3, 2 );
set10( d[ 7 ], 7, 6, 5, 9, 8, 2, 1, 0, 4, 3 );
set10( d[ 8 ], 8, 7, 6, 5, 9, 3, 2, 1, 0, 4 );
set10( d[ 9 ], 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 );
set10( inv, 0, 4, 3, 2, 1, 5, 6, 7, 8, 9 );
set10( p[ 0 ], 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 );
set10( p[ 1 ], 1, 5, 7, 6, 2, 8, 3, 0, 9, 4 );
set10( p[ 2 ], 5, 8, 0, 3, 7, 9, 6, 1, 4, 2 );
set10( p[ 3 ], 8, 9, 1, 6, 0, 4, 3, 5, 2, 7 );
set10( p[ 4 ], 9, 4, 5, 3, 1, 2, 6, 8, 7, 0 );
set10( p[ 5 ], 4, 2, 8, 6, 5, 7, 3, 9, 0, 1 );
set10( p[ 6 ], 2, 7, 9, 3, 8, 0, 6, 4, 1, 5 );
set10( p[ 7 ], 7, 0, 4, 6, 9, 1, 3, 2, 5, 8 );
END init ;
(* calculates the check digit of s or validates s using the Verhoeff algorithm *)
(* depending on whether validate is FALSE or TRUE *)
(* returns the check digit or zero/non-zero if s is valid/invalid *)
(* if table is TRUE, details of the calculations are shown *)
PROCEDURE VerhoeffAlgorithm( s : ARRAY OF CHAR; validate, table : BOOLEAN ) : INTEGER;
VAR c, le, efl, k, result : INTEGER;
PROCEDURE handleDigit( digit : CHAR; c, k, le : INTEGER; table : BOOLEAN ) : INTEGER;
VAR nidx, pidx, result : INTEGER;
BEGIN
nidx := ORD( digit ) - ORD( "0" );
pidx := p[ ( le - k ) MOD 8, nidx ];
result := d[ c, pidx ];
IF table THEN
Out.String( " " );Out.Int( le - k, 2 );Out.String( " " );Out.Int( nidx, 0 );
Out.String( " " );Out.Int( pidx, 0 );Out.String( " " );Out.Int( result, 0 );Out.Ln
END
RETURN result
END handleDigit;
BEGIN
IF table THEN
IF validate THEN Out.String( "Validation" ) ELSE Out.String( "Check digit" ) END;
Out.String( " calculations for '" );Out.String( s );Out.String( "':" );Out.Ln;
Out.String( " i ni p[i,ni] c" );Out.Ln;Out.String( " ------------------" );Out.Ln;
END;
c := 0;
le := Strings.Length( s );
IF validate THEN efl := le ELSE efl := le + 1 END;
IF ~ validate THEN
(* calculating - pretend there is an extra 0 at the end of the string *)
c := handleDigit( "0", c, efl - 1, efl - 1, table )
END;
FOR k := le - 1 TO 0 BY -1 DO
c := handleDigit( s[ k ], c, k, efl - 1, table )
END;
IF table & ~ validate THEN
Out.String( " inv[" );Out.Int( c, 0 );Out.String( "] = " );Out.Int( inv[ c ], 0 );Out.Ln
END;
IF ~ validate THEN result := inv[ c ] ELSE result := c END
RETURN result
END VerhoeffAlgorithm ;
(* returns TRUE if s is valid according to the Verhoeff algorithm, FALSE otherwise *)
(* if table is TRUE, details of the calculations are shown *)
PROCEDURE VerhoeffValidation( s : ARRAY OF CHAR; table : BOOLEAN ) : BOOLEAN;
BEGIN
RETURN VerhoeffAlgorithm( s, TRUE, table ) = 0
END VerhoeffValidation ;
(* returns the check digit of s according to the Verhoeff algorithm, FALSE otherwise *)
(* if table is TRUE, details of the calculations are shown *)
PROCEDURE VerhoeffCheckDigit( s : ARRAY OF CHAR; table : BOOLEAN ) : INTEGER;
BEGIN
RETURN VerhoeffAlgorithm( s, FALSE, table )
END VerhoeffCheckDigit ;
PROCEDURE testCases; (* run the Verhoeff algorithm task test cases *)
PROCEDURE oneTest( s : ARRAY OF CHAR; table : BOOLEAN );
VAR c : INTEGER;
PROCEDURE oneValidationTest( s : ARRAY OF CHAR; extraDigit : CHAR; table : BOOLEAN );
VAR result : ARRAY 16 OF CHAR;
sd : ARRAY 32 OF CHAR;
sLen : INTEGER;
BEGIN
sd := s;
sLen := Strings.Length( sd );
sd[ sLen ] := extraDigit;
sd[ sLen + 1 ] := 0X;
IF VerhoeffValidation( sd, table ) THEN
result := "correct"
ELSE
result := "incorrect"
END;
Out.String( "Validation for '" );Out.String( sd );Out.String( "' -> " );
Out.String( result );Out.String( "." );Out.Ln
END oneValidationTest ;
BEGIN
c := VerhoeffCheckDigit( s, table );
Out.String( "The check digit for '" );Out.String( s );
Out.String( "' is '" );Out.Int( c, 0 );Out.String( "'" );Out.Ln;
oneValidationTest( s, CHR( c + ORD( "0" ) ), table );
oneValidationTest( s, "9", table )
END oneTest ;
BEGIN
oneTest( "236", TRUE ); Out.Ln;Out.Ln;
oneTest( "12345", TRUE ); Out.Ln;Out.Ln;
oneTest( "123456789012", FALSE );
END testCases;
BEGIN
init;
testCases
END VerhoeffAlgorithm.

View file

@ -0,0 +1,56 @@
local fmt = require "fmt"
local d = {
{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}
}
local inv = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}
local p = {
{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}
}
local function verhoeff(s, validate, table)
if table then
print($"{validate ? "Validation" : "Check digit"} calculations for '{s}':\n")
print(" i nᵢ p[i,nᵢ] c")
print("------------------")
end
if !validate then s ..= "0" end
local c = 0
local le = #s - 1
for i = le, 0, -1 do
local ni = s[i + 1]:byte() - 48
local pi = p[(le - i) % 8 + 1][ni + 1]
c = d[c + 1][pi + 1]
if table then fmt.print("%2d %d %d %d", le - i, ni, pi, c) end
end
if table and !validate then print($"\ninv[{c + 1}] = {inv[c + 1]}") end
return !validate ? inv[c + 1] : c == 0
end
local sts = {{"236", true}, {"12345", true}, {"123456789012", false}}
for sts as st do
local c = verhoeff(st[1], false, st[2])
print($"\nThe check digit for '{st[1]}' is '{c}'\n")
for {st[1] .. tostring(c), st[1] .. "9"} as stc do
local v = verhoeff(stc, true, st[2])
print($"\nThe validation for '{stc}' is {v ? "correct" : "incorrect"}.\n")
end
end

View file

@ -0,0 +1,84 @@
options(scipen=999) # prevent scientific notation
multiplicationtable <- matrix(c(
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
), nrow=10, byrow=TRUE)
permutationtable <- matrix(c(
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
), nrow=8, byrow=TRUE)
inv <- c(0,4,3,2,1,5,6,7,8,9)
verhoeffchecksum <- function(n, validate=TRUE, terse=TRUE, verbose=FALSE) {
nstr <- as.character(n) # keep number as string
if (verbose) {
cat("\n", ifelse(validate, "Validation", "Check digit"),
" calculations for '", nstr, "':\n\n",
" i nᵢ p[i,nᵢ] c\n------------------\n", sep="")
}
dig <- as.integer(strsplit(if (validate) nstr else paste0(nstr, "0"), "")[[1]])
dig <- rev(dig) # Julia uses reverse
c <- 0
for (i in seq_along(dig)) {
ni <- dig[i]
p <- permutationtable[(i - 1) %% 8 + 1, ni + 1]
c <- multiplicationtable[c + 1, p + 1]
if (verbose) {
cat(sprintf("%2d %d %d %d\n", i-1, ni, p, c))
}
}
if (verbose && !validate) {
cat("\ninv[", c, "] = ", inv[c + 1], "\n", sep="")
}
if (!terse) {
if (validate) {
cat("\nThe validation for '", nstr, "' is ",
ifelse(c == 0, "correct", "incorrect"), ".\n", sep="")
} else {
cat("\nThe check digit for '", nstr, "' is '", inv[c + 1], "'\n", sep="")
}
}
if (validate) {
return(c == 0)
} else {
return(inv[c + 1])
}
}
# Test runs
tests <- list(
list("236", FALSE, FALSE, TRUE),
list("2363", TRUE, FALSE, TRUE),
list("2369", TRUE, FALSE, TRUE),
list("12345", FALSE, FALSE, TRUE),
list("123451", TRUE, FALSE, TRUE),
list("123459", TRUE, FALSE, TRUE),
list("123456789012", FALSE, FALSE),
list("1234567890120", TRUE, FALSE),
list("1234567890129", TRUE, FALSE)
)
for (args in tests) {
do.call(verhoeffchecksum, args)
}

View file

@ -0,0 +1,113 @@
/* REXX implementation of the Verhoeff Algorithm */
Call init -- fill the tables (data taken from Java Script)
Call check 236,1 -- compute check digit AND validate numbers
Call check 12345,1 -- "
Call check 123456789012,0 -- validate numbers
Exit
check:
Parse Arg number,details
numberx=number
Say 'Check digit calculations for' number
d=compute(number||0,details,1)
Say 'The check digit for' numberx 'is' d
Call check2 numberx||d,details
Call check2 numberx||9,details
Return
check2:
Parse Arg number,details
If details Then
Say 'Validation calculations for' number
d=compute(number,details,0)
If d=0 Then
Say 'The validation for' number' is correct.'
Else
Say 'The validation for' number' is incorrect.'
Return
compute:
Parse Arg number,details,show_inv
Call details ''
Call details ' i ni p[i, ni] c'
Call details '-------------------'
c=0
le=length(number)-1
Do i=le To 0 By-1
ni=substr(number,i+1,1)
z=(le-i)//8
pi=perm.z.ni
c=mult.c.pi
Call details right(le-i,2) right(ni,2) right(pi,7) right(c,5)
End
If show_inv Then
Call details "inverse["c"] = "invt.c
Return invt.c
details:
If details Then
Say arg(1)
Return
init:
Call mk_mult '[[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]]'
Call mk_invt '[0, 4, 3, 2, 1, 5, 6, 7, 8, 9]'
Call mk_perm '[[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]]'
Return
mk_mult:
Parse Arg list
list=translate(list,' ','[],')
Do i=0 to 9
Do j=0 to 9
Parse Var list mult.i.j list
End
End
Return
mk_invt:
Parse Arg list
list=translate(list,' ','[],')
Do i=0 to 9
Parse Var list invt.i list
End
Return
mk_perm:
Parse Arg list
list=translate(list,' ','[],')
Do i=0 to 9
Do j=0 to 9
Parse Var list perm.i.j list
End
End
Return
show_mult:
If details Then Say'show_mult'
Do i=0 To 9
l=''
Do j=1 To 9
l=l mult.i.j
End
Call details l
End
return