Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Verhoeff-algorithm/00-META.yaml
Normal file
2
Task/Verhoeff-algorithm/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Verhoeff_algorithm
|
||||
20
Task/Verhoeff-algorithm/00-TASK.txt
Normal file
20
Task/Verhoeff-algorithm/00-TASK.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
;Description
|
||||
The [https://en.wikipedia.org/wiki/Verhoeff_algorithm Verhoeff algorithm] is a checksum formula for error detection developed by the Dutch mathematician Jacobus Verhoeff and first published in 1969. It was the first decimal check digit algorithm which detects all single-digit errors, and all transposition errors involving two adjacent digits, which was at the time thought impossible with such a code.
|
||||
|
||||
As the workings of the algorithm are clearly described in the linked Wikipedia article they will not be repeated here.
|
||||
|
||||
;Task:
|
||||
Write routines, methods, procedures etc. in your language to generate a Verhoeff checksum digit for non-negative integers of any length and to validate the result. A combined routine is also acceptable.
|
||||
|
||||
The more mathematically minded may prefer to generate the 3 tables required from the description provided rather than to hard-code them.
|
||||
|
||||
Write your routines in such a way that they can optionally display digit by digit calculations as in the Wikipedia example.
|
||||
|
||||
Use your routines to calculate check digits for the integers: '''236''', '''12345''' and '''123456789012''' and then validate them. Also attempt to validate the same integers if the check digits in all cases were '''9''' rather than what they actually are.
|
||||
|
||||
Display digit by digit calculations for the first two integers but not for the third.
|
||||
|
||||
;Related task:
|
||||
* [[Damm algorithm]]
|
||||
<br><br>
|
||||
|
||||
55
Task/Verhoeff-algorithm/11l/verhoeff-algorithm.11l
Normal file
55
Task/Verhoeff-algorithm/11l/verhoeff-algorithm.11l
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
V MULTIPLICATION_TABLE = [[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]]
|
||||
|
||||
V INV = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
|
||||
|
||||
V PERMUTATION_TABLE = [[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]]
|
||||
|
||||
F verhoeffchecksum(n, validate = 1B, terse = 1B, verbose = 0B)
|
||||
‘
|
||||
Calculate the Verhoeff checksum over `n`.
|
||||
Terse mode or with single argument: return True if valid (last digit is a correct check digit).
|
||||
If checksum mode, return the expected correct checksum digit.
|
||||
If validation mode, return True if last digit checks correctly.
|
||||
’
|
||||
I verbose
|
||||
print(("\n"(I validate {‘Validation’} E ‘Check digit’))‘ ’(‘calculations for ’n":\n\n i ni p[i,ni] c\n------------------"))
|
||||
V (c, dig) = (0, Array(String(I validate {n} E 10 * n)))
|
||||
L(ni) reversed(dig)
|
||||
V i = L.index
|
||||
V p = :PERMUTATION_TABLE[i % 8][Int(ni)]
|
||||
c = :MULTIPLICATION_TABLE[c][p]
|
||||
I verbose
|
||||
print(f:‘{i:2} {ni} {p} {c}’)
|
||||
|
||||
I verbose & !validate
|
||||
print("\ninv("c‘) = ’:INV[c])
|
||||
I !terse
|
||||
print(I validate {"\nThe validation for '"n‘' is ’(I c == 0 {‘correct’} E ‘incorrect’)‘.’} E "\nThe check digit for '"n‘' is ’:INV[c]‘.’)
|
||||
R I validate {c == 0} E :INV[c]
|
||||
|
||||
L(n, va, t, ve) [(Int64(236), 0B, 0B, 1B),
|
||||
(Int64(2363), 1B, 0B, 1B),
|
||||
(Int64(2369), 1B, 0B, 1B),
|
||||
(Int64(12345), 0B, 0B, 1B),
|
||||
(Int64(123451), 1B, 0B, 1B),
|
||||
(Int64(123459), 1B, 0B, 1B),
|
||||
(Int64(123456789012), 0B, 0B, 0B),
|
||||
(Int64(1234567890120), 1B, 0B, 0B),
|
||||
(Int64(1234567890129), 1B, 0B, 0B)]
|
||||
verhoeffchecksum(n, va, t, ve)
|
||||
81
Task/Verhoeff-algorithm/C++/verhoeff-algorithm.cpp
Normal file
81
Task/Verhoeff-algorithm/C++/verhoeff-algorithm.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <iomanip>
|
||||
|
||||
typedef std::pair<std::string, bool> data;
|
||||
|
||||
const std::array<const std::array<int32_t, 10>, 10> multiplication_table = { {
|
||||
{ 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 }
|
||||
} };
|
||||
|
||||
const std::array<int32_t, 10> inverse = { 0, 4, 3, 2, 1, 5, 6, 7, 8, 9 };
|
||||
|
||||
const std::array<const std::array<int32_t, 10>, 8> permutation_table = { {
|
||||
{ 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 }
|
||||
} };
|
||||
|
||||
int32_t verhoeff_checksum(std::string number, bool doValidation, bool doDisplay) {
|
||||
if ( doDisplay ) {
|
||||
std::string calculationType = doValidation ? "Validation" : "Check digit";
|
||||
std::cout << calculationType << " calculations for " << number << "\n" << std::endl;
|
||||
std::cout << " i ni p[i, ni] c" << std::endl;
|
||||
std::cout << "-------------------" << std::endl;
|
||||
}
|
||||
|
||||
if ( ! doValidation ) {
|
||||
number += "0";
|
||||
}
|
||||
|
||||
int32_t c = 0;
|
||||
const int32_t le = number.length() - 1;
|
||||
for ( int32_t i = le; i >= 0; i-- ) {
|
||||
const int32_t ni = number[i] - '0';
|
||||
const int32_t pi = permutation_table[(le - i) % 8][ni];
|
||||
c = multiplication_table[c][pi];
|
||||
|
||||
if ( doDisplay ) {
|
||||
std::cout << std::setw(2) << le - i << std::setw(3) << ni
|
||||
<< std::setw(8) << pi << std::setw(6) << c << "\n" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if ( doDisplay && ! doValidation ) {
|
||||
std::cout << "inverse[" << c << "] = " << inverse[c] << "\n" << std::endl;;
|
||||
}
|
||||
|
||||
return doValidation ? c == 0 : inverse[c];
|
||||
}
|
||||
|
||||
int main( ) {
|
||||
const std::array<data, 3> tests = {
|
||||
std::make_pair("123", true), std::make_pair("12345", true), std::make_pair("123456789012", false) };
|
||||
|
||||
for ( data test : tests ) {
|
||||
int32_t digit = verhoeff_checksum(test.first, false, test.second);
|
||||
std::cout << "The check digit for " << test.first << " is " << digit << "\n" << std::endl;
|
||||
|
||||
std::string numbers[2] = { test.first + std::to_string(digit), test.first + "9" };
|
||||
for ( std::string number : numbers ) {
|
||||
digit = verhoeff_checksum(number, true, test.second);
|
||||
std::string result = ( digit == 1 ) ? "correct" : "incorrect";
|
||||
std::cout << "The validation for " << number << " is " << result << ".\n" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Task/Verhoeff-algorithm/C/verhoeff-algorithm.c
Normal file
65
Task/Verhoeff-algorithm/C/verhoeff-algorithm.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const int d[][10] = {
|
||||
{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},
|
||||
};
|
||||
|
||||
static const int inv[] = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9};
|
||||
|
||||
static const int p[][10] = {
|
||||
{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},
|
||||
};
|
||||
|
||||
int verhoeff(const char* s, bool validate, bool verbose) {
|
||||
if (verbose) {
|
||||
const char* t = validate ? "Validation" : "Check digit";
|
||||
printf("%s calculations for '%s':\n\n", t, s);
|
||||
puts(u8" i n\xE1\xB5\xA2 p[i,n\xE1\xB5\xA2] c");
|
||||
puts("------------------");
|
||||
}
|
||||
int len = strlen(s);
|
||||
if (validate)
|
||||
--len;
|
||||
int c = 0;
|
||||
for (int i = len; i >= 0; --i) {
|
||||
int ni = (i == len && !validate) ? 0 : s[i] - '0';
|
||||
assert(ni >= 0 && ni < 10);
|
||||
int pi = p[(len - i) % 8][ni];
|
||||
c = d[c][pi];
|
||||
if (verbose)
|
||||
printf("%2d %d %d %d\n", len - i, ni, pi, c);
|
||||
}
|
||||
if (verbose && !validate)
|
||||
printf("\ninv[%d] = %d\n", c, inv[c]);
|
||||
return validate ? c == 0 : inv[c];
|
||||
}
|
||||
|
||||
int main() {
|
||||
const char* ss[3] = {"236", "12345", "123456789012"};
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const char* s = ss[i];
|
||||
bool verbose = i < 2;
|
||||
int c = verhoeff(s, false, verbose);
|
||||
printf("\nThe check digit for '%s' is '%d'.\n", s, c);
|
||||
int len = strlen(s);
|
||||
char sc[len + 2];
|
||||
strncpy(sc, s, len + 2);
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
sc[len] = (j == 0) ? c + '0' : '9';
|
||||
int v = verhoeff(sc, true, verbose);
|
||||
printf("\nThe validation for '%s' is %s.\n", sc,
|
||||
v ? "correct" : "incorrect");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
22
Task/Verhoeff-algorithm/F-Sharp/verhoeff-algorithm.fs
Normal file
22
Task/Verhoeff-algorithm/F-Sharp/verhoeff-algorithm.fs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Verhoeff algorithm. Nigel Galloway: August 26th., 2021
|
||||
let d,inv,p=let 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|]
|
||||
let 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|]
|
||||
let inv=[|0;4;3;2;1;5;6;7;8;9|] in (fun n g->d.[10*n+g]),(fun g->inv.[g]),(fun n g->p.[10*(n%8)+g])
|
||||
let fN g=Seq.unfold(fun(i,g,l)->if i=0I then None else let ni=int(i%10I) in let l=d l (p g ni) in Some((ni,l),(i/10I,g+1,l)))(g,0,0)
|
||||
let csum g=let _,g=Seq.last(fN g) in inv g
|
||||
let printTable g=printfn $"Work Table for %A{g}\n i nᵢ p[i,nᵢ] c\n--------------"; fN g|>Seq.iteri(fun i (n,g)->printfn $"%d{i} %d{n} %d{p i n} %d{g}")
|
||||
printTable 2360I
|
||||
printfn $"\nThe CheckDigit for 236 is %d{csum 2360I}\n"
|
||||
printTable 2363I
|
||||
printfn $"\nThe assertion that 2363 is valid is %A{csum 2363I=0}\n"
|
||||
printTable 2369I
|
||||
printfn $"\nThe assertion that 2369 is valid is %A{csum 2369I=0}\n"
|
||||
printTable 123450I
|
||||
printfn $"\nThe CheckDigit for 12345 is %d{csum 123450I}\n"
|
||||
printTable 123451I
|
||||
printfn $"\nThe assertion that 123451 is valid is %A{csum 123451I=0}\n"
|
||||
printTable 123459I
|
||||
printfn $"\nThe assertion that 123459 is valid is %A{csum 123459I=0}"
|
||||
printfn $"The CheckDigit for 123456789012 is %d{csum 1234567890120I}"
|
||||
printfn $"The assertion that 1234567890120 is valid is %A{csum 1234567890120I=0}"
|
||||
printfn $"The assertion that 1234567890129 is valid is %A{csum 1234567890129I=0}"
|
||||
78
Task/Verhoeff-algorithm/Go/verhoeff-algorithm.go
Normal file
78
Task/Verhoeff-algorithm/Go/verhoeff-algorithm.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var d = [][]int{
|
||||
{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},
|
||||
}
|
||||
|
||||
var inv = []int{0, 4, 3, 2, 1, 5, 6, 7, 8, 9}
|
||||
|
||||
var p = [][]int{
|
||||
{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 string, validate, table bool) interface{} {
|
||||
if table {
|
||||
t := "Check digit"
|
||||
if validate {
|
||||
t = "Validation"
|
||||
}
|
||||
fmt.Printf("%s calculations for '%s':\n\n", t, s)
|
||||
fmt.Println(" i nᵢ p[i,nᵢ] c")
|
||||
fmt.Println("------------------")
|
||||
}
|
||||
if !validate {
|
||||
s = s + "0"
|
||||
}
|
||||
c := 0
|
||||
le := len(s) - 1
|
||||
for i := le; i >= 0; i-- {
|
||||
ni := int(s[i] - 48)
|
||||
pi := p[(le-i)%8][ni]
|
||||
c = d[c][pi]
|
||||
if table {
|
||||
fmt.Printf("%2d %d %d %d\n", le-i, ni, pi, c)
|
||||
}
|
||||
}
|
||||
if table && !validate {
|
||||
fmt.Printf("\ninv[%d] = %d\n", c, inv[c])
|
||||
}
|
||||
if !validate {
|
||||
return inv[c]
|
||||
}
|
||||
return c == 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
ss := []string{"236", "12345", "123456789012"}
|
||||
ts := []bool{true, true, false, true}
|
||||
for i, s := range ss {
|
||||
c := verhoeff(s, false, ts[i]).(int)
|
||||
fmt.Printf("\nThe check digit for '%s' is '%d'\n\n", s, c)
|
||||
for _, sc := range []string{s + string(c+48), s + "9"} {
|
||||
v := verhoeff(sc, true, ts[i]).(bool)
|
||||
ans := "correct"
|
||||
if !v {
|
||||
ans = "incorrect"
|
||||
}
|
||||
fmt.Printf("\nThe validation for '%s' is %s\n\n", sc, ans)
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Task/Verhoeff-algorithm/J/verhoeff-algorithm-1.j
Normal file
30
Task/Verhoeff-algorithm/J/verhoeff-algorithm-1.j
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
cyc=: | +/~@i. NB. cyclic group, order y
|
||||
ac=: |(+-/~@i.) NB. anticyclic group, order y
|
||||
a2n=: (+#)@ NB. add 2^n
|
||||
di=: (cyc,.cyc a2n),((ac a2n),.ac)
|
||||
|
||||
D=: di 5
|
||||
INV=: ,I.0=D
|
||||
P=: {&(C.1 5 8 9 4 2 7 0;3 6)^:(i.8) i.10
|
||||
|
||||
verhoeff=: {{
|
||||
c=. 0
|
||||
for_N. |.10 #.inv y do.
|
||||
c=. D{~<c,P{~<(8|N_index),N
|
||||
end.
|
||||
}}
|
||||
|
||||
traceverhoeff=: {{
|
||||
r=. EMPTY
|
||||
c=. 0
|
||||
for_N. |.10 #.inv y do.
|
||||
c0=. c
|
||||
c=. D{~<c,p=.P{~<(j=.8|N_index),N
|
||||
r=. r, c,p,j,N_index,N,c0
|
||||
end.
|
||||
labels=. cut 'cᵢ p[i,nᵢ] i nᵢ n cₒ'
|
||||
1 1}.}:~.":labels,(<;._1"1~[:*/' '=])' ',.":r
|
||||
}}
|
||||
|
||||
checkdigit=: INV {~ verhoeff@*&10
|
||||
valid=: 0 = verhoeff
|
||||
30
Task/Verhoeff-algorithm/J/verhoeff-algorithm-2.j
Normal file
30
Task/Verhoeff-algorithm/J/verhoeff-algorithm-2.j
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
checkdigit 236 12345 123456789012
|
||||
3 1 0
|
||||
valid 2363
|
||||
1
|
||||
valid 123451
|
||||
1
|
||||
valid 1234567890120
|
||||
1
|
||||
valid 2369
|
||||
0
|
||||
valid 123459
|
||||
0
|
||||
valid 1234567890129
|
||||
0
|
||||
traceverhoeff 2363
|
||||
cᵢ│p[i,nᵢ]│i│nᵢ│n│cₒ│
|
||||
──┼───────┼─┼──┼─┼──┤
|
||||
3 │3 │0│0 │3│0 │
|
||||
1 │3 │1│1 │6│3 │
|
||||
4 │3 │2│2 │3│1 │
|
||||
0 │1 │3│3 │2│4 │
|
||||
traceverhoeff 123451
|
||||
cᵢ│p[i,nᵢ]│i│nᵢ│n│cₒ│
|
||||
──┼───────┼─┼──┼─┼──┤
|
||||
1 │1 │0│0 │1│0 │
|
||||
9 │8 │1│1 │5│1 │
|
||||
2 │7 │2│2 │4│9 │
|
||||
8 │6 │3│3 │3│2 │
|
||||
3 │5 │4│4 │2│8 │
|
||||
0 │2 │5│5 │1│3 │
|
||||
87
Task/Verhoeff-algorithm/Java/verhoeff-algorithm.java
Normal file
87
Task/Verhoeff-algorithm/Java/verhoeff-algorithm.java
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class VerhoeffAlgorithm {
|
||||
|
||||
public static void main(String[] args) {
|
||||
initialise();
|
||||
|
||||
List<List<Object>> tests = List.of(
|
||||
List.of( "236", true ), List.of( "12345", true ), List.of( "123456789012", false ) );
|
||||
|
||||
for ( List<Object> test : tests ) {
|
||||
Object object = verhoeffChecksum((String) test.get(0), false, (boolean) test.get(1));
|
||||
System.out.println("The check digit for " + test.get(0) + " is " + object + "\n");
|
||||
|
||||
for ( String number : List.of( test.get(0) + String.valueOf(object), test.get(0) + "9" ) ) {
|
||||
object = verhoeffChecksum(number, true, (boolean) test.get(1));
|
||||
String result = (boolean) object ? "correct" : "incorrect";
|
||||
System.out.println("The validation for " + number + " is " + result + ".\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Object verhoeffChecksum(String number, boolean doValidation, boolean doDisplay) {
|
||||
if ( doDisplay ) {
|
||||
String calculationType = doValidation ? "Validation" : "Check digit";
|
||||
System.out.println(calculationType + " calculations for " + number + "\n");
|
||||
System.out.println(" i ni p[i, ni] c");
|
||||
System.out.println("-------------------");
|
||||
}
|
||||
|
||||
if ( ! doValidation ) {
|
||||
number += "0";
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
final int le = number.length() - 1;
|
||||
for ( int i = le; i >= 0; i-- ) {
|
||||
final int ni = number.charAt(i) - '0';
|
||||
final int pi = permutationTable.get((le - i) % 8).get(ni);
|
||||
c = multiplicationTable.get(c).get(pi);
|
||||
|
||||
if ( doDisplay ) {
|
||||
System.out.println(String.format("%2d%3d%8d%6d\n", le - i, ni, pi, c));
|
||||
}
|
||||
}
|
||||
|
||||
if ( doDisplay && ! doValidation ) {
|
||||
System.out.println("inverse[" + c + "] = " + inverse.get(c) + "\n");
|
||||
}
|
||||
|
||||
return doValidation ? c == 0 : inverse.get(c);
|
||||
}
|
||||
|
||||
private static void initialise() {
|
||||
multiplicationTable = List.of(
|
||||
List.of( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
|
||||
List.of( 1, 2, 3, 4, 0, 6, 7, 8, 9, 5 ),
|
||||
List.of( 2, 3, 4, 0, 1, 7, 8, 9, 5, 6 ),
|
||||
List.of( 3, 4, 0, 1, 2, 8, 9, 5, 6, 7 ),
|
||||
List.of( 4, 0, 1, 2, 3, 9, 5, 6, 7, 8 ),
|
||||
List.of( 5, 9, 8, 7, 6, 0, 4, 3, 2, 1 ),
|
||||
List.of( 6, 5, 9, 8, 7, 1, 0, 4, 3, 2 ),
|
||||
List.of( 7, 6, 5, 9, 8, 2, 1, 0, 4, 3 ),
|
||||
List.of( 8, 7, 6, 5, 9, 3, 2, 1, 0, 4 ),
|
||||
List.of( 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 )
|
||||
);
|
||||
|
||||
inverse = Arrays.asList( 0, 4, 3, 2, 1, 5, 6, 7, 8, 9 );
|
||||
|
||||
permutationTable = List.of(
|
||||
List.of( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
|
||||
List.of( 1, 5, 7, 6, 2, 8, 3, 0, 9, 4 ),
|
||||
List.of( 5, 8, 0, 3, 7, 9, 6, 1, 4, 2 ),
|
||||
List.of( 8, 9, 1, 6, 0, 4, 3, 5, 2, 7 ),
|
||||
List.of( 9, 4, 5, 3, 1, 2, 6, 8, 7, 0 ),
|
||||
List.of( 4, 2, 8, 6, 5, 7, 3, 9, 0, 1 ),
|
||||
List.of( 2, 7, 9, 3, 8, 0, 6, 4, 1, 5 ),
|
||||
List.of( 7, 0, 4, 6, 9, 1, 3, 2, 5, 8 )
|
||||
);
|
||||
}
|
||||
|
||||
private static List<List<Integer>> multiplicationTable;
|
||||
private static List<Integer> inverse;
|
||||
private static List<List<Integer>> permutationTable;
|
||||
|
||||
}
|
||||
74
Task/Verhoeff-algorithm/Jq/verhoeff-algorithm.jq
Normal file
74
Task/Verhoeff-algorithm/Jq/verhoeff-algorithm.jq
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
|
||||
|
||||
def 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]
|
||||
];
|
||||
|
||||
def inv: [0, 4, 3, 2, 1, 5, 6, 7, 8, 9];
|
||||
|
||||
def 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]
|
||||
];
|
||||
|
||||
# Output: an object: {emit, c}
|
||||
def verhoeff($s; $validate; $table):
|
||||
|
||||
{emit:
|
||||
(if $table then
|
||||
["\(if $validate then "Validation" else "Check digit" end) calculations for '\($s)':\n",
|
||||
" i nᵢ p[i,nᵢ] c",
|
||||
"------------------"]
|
||||
else []
|
||||
end),
|
||||
s: (if $validate then $s else $s + "0" end),
|
||||
c: 0 }
|
||||
| ((.s|length) - 1) as $le
|
||||
| reduce range($le; -1; -1) as $i (.;
|
||||
(.s[$i:$i+1]|explode[] - 48) as $ni
|
||||
| (p[($le-$i) % 8][$ni]) as $pi
|
||||
| .c = d[.c][$pi]
|
||||
| if $table
|
||||
then .emit += ["\($le-$i|lpad(2)) \($ni) \($pi) \(.c)"]
|
||||
else .
|
||||
end )
|
||||
| if $table and ($validate|not)
|
||||
then .emit += ["\ninv[\(.c)] = \(inv[.c])"]
|
||||
else .
|
||||
end
|
||||
| .c = (if $validate then (.c == 0) else inv[.c] end);
|
||||
|
||||
def sts: [
|
||||
["236", true],
|
||||
["12345", true],
|
||||
["123456789012", false]];
|
||||
|
||||
def task:
|
||||
sts[]
|
||||
| . as $st
|
||||
| verhoeff($st[0]; false; $st[1]) as {c: $c, emit: $emit}
|
||||
| $emit[],
|
||||
"\nThe check digit for '\($st[0])' is '\($c)'\n",
|
||||
( ($st[0] + ($c|tostring)), ($st[0] + "9")
|
||||
| . as $stc
|
||||
| verhoeff($stc; true; $st[1]) as {emit: $emit, c: $v}
|
||||
| (if $v then "correct" else "incorrect" end) as $v
|
||||
| $emit[],
|
||||
"\nThe validation for '\($stc)' is \($v).\n" );
|
||||
|
||||
task
|
||||
54
Task/Verhoeff-algorithm/Julia/verhoeff-algorithm.julia
Normal file
54
Task/Verhoeff-algorithm/Julia/verhoeff-algorithm.julia
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
const multiplicationtable = [
|
||||
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]
|
||||
|
||||
const permutationtable = [
|
||||
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]
|
||||
|
||||
const inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
|
||||
|
||||
"""
|
||||
verhoeffchecksum(n::Integer, validate=true, terse=true, verbose=false)
|
||||
|
||||
Calculate the Verhoeff checksum over `n`.
|
||||
Terse mode or with single argument: return true if valid (last digit is a correct check digit).
|
||||
If checksum mode, return the expected correct checksum digit.
|
||||
If validation mode, return true if last digit checks correctly.
|
||||
"""
|
||||
function verhoeffchecksum(n::Integer, validate=true, terse=true, verbose=false)
|
||||
verbose && println("\n", validate ? "Validation" : "Check digit",
|
||||
" calculations for '$n':\n\n", " i nᵢ p[i,nᵢ] c\n------------------")
|
||||
# transform number list
|
||||
c, dig = 0, reverse(digits(validate ? n : 10 * n))
|
||||
for i in length(dig):-1:1
|
||||
ni = dig[i]
|
||||
p = permutationtable[(length(dig) - i) % 8 + 1, ni + 1]
|
||||
c = multiplicationtable[c + 1, p + 1]
|
||||
verbose && println(lpad(length(dig) - i, 2), " $ni $p $c")
|
||||
end
|
||||
verbose && !validate && println("\ninv($c) = $(inv[c + 1])")
|
||||
!terse && println(validate ? "\nThe validation for '$n' is $(c == 0 ?
|
||||
"correct" : "incorrect")." : "\nThe check digit for '$n' is $(inv[c + 1]).")
|
||||
return validate ? c == 0 : inv[c + 1]
|
||||
end
|
||||
|
||||
for args in [(236, false, false, true), (2363, true, false, true), (2369, true, false, true),
|
||||
(12345, false, false, true), (123451, true, false, true), (123459, true, false, true),
|
||||
(123456789012, false, false), (1234567890120, true, false), (1234567890129, true, false)]
|
||||
verhoeffchecksum(args...)
|
||||
end
|
||||
82
Task/Verhoeff-algorithm/Nim/verhoeff-algorithm.nim
Normal file
82
Task/Verhoeff-algorithm/Nim/verhoeff-algorithm.nim
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import strformat
|
||||
|
||||
const
|
||||
|
||||
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]]
|
||||
|
||||
type Digit = 0..9
|
||||
|
||||
proc verhoeff[T: SomeInteger](n: T; validate, verbose = false): T =
|
||||
## Compute or validate a check digit.
|
||||
## Return the check digit if computation or the number with the check digit
|
||||
## removed if validation.
|
||||
## If not in verbose mode, an exception is raised if validation failed.
|
||||
|
||||
doAssert n >= 0, "Argument must not be negative."
|
||||
|
||||
# Extract digits.
|
||||
var digits: seq[Digit]
|
||||
if not validate: digits.add 0
|
||||
var val = n
|
||||
while val != 0:
|
||||
digits.add val mod 10
|
||||
val = val div 10
|
||||
|
||||
if verbose:
|
||||
echo if validate: &"Check digit validation for {n}:" else: &"Check digit computation for {n}:"
|
||||
echo " i ni p(i, ni) c"
|
||||
|
||||
# Compute c.
|
||||
var c = 0
|
||||
for i, ni in digits:
|
||||
let p = P[i mod 8][ni]
|
||||
c = D[c][p]
|
||||
if verbose: echo &"{i:2} {ni} {p} {c}"
|
||||
|
||||
if validate:
|
||||
if verbose:
|
||||
let verb = if c == 0: "is" else: "is not"
|
||||
echo &"Validation {verb} successful.\n"
|
||||
elif c != 0:
|
||||
raise newException(ValueError, &"Check digit validation failed for {n}.")
|
||||
result = n div 10
|
||||
|
||||
else:
|
||||
result = Inv[c]
|
||||
if verbose: echo &"The check digit for {n} is {result}.\n"
|
||||
|
||||
|
||||
for n in [236, 12345]:
|
||||
let d = verhoeff(n, false, true)
|
||||
discard verhoeff(10 * n + d, true, true)
|
||||
discard verhoeff(10 * n + 9, true, true)
|
||||
|
||||
let n = 123456789012
|
||||
let d = verhoeff(n)
|
||||
echo &"Check digit for {n} is {d}."
|
||||
discard verhoeff(10 * n + d, true)
|
||||
echo &"Check digit validation was successful for {10 * n + d}."
|
||||
try:
|
||||
discard verhoeff(10 * n + 9, true)
|
||||
except ValueError:
|
||||
echo getCurrentExceptionMsg()
|
||||
63
Task/Verhoeff-algorithm/Perl/verhoeff-algorithm.pl
Normal file
63
Task/Verhoeff-algorithm/Perl/verhoeff-algorithm.pl
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#!/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";
|
||||
}
|
||||
63
Task/Verhoeff-algorithm/Phix/verhoeff-algorithm.phix
Normal file
63
Task/Verhoeff-algorithm/Phix/verhoeff-algorithm.phix
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)},</span>
|
||||
<span style="color: #000000;">inv</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[$],{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">}))</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]))</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]))</span>
|
||||
<span style="color: #000000;">inv</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..</span><span style="color: #000000;">5</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">inv</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..</span><span style="color: #000000;">5</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">7</span> <span style="color: #008080;">do</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[$],{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">}))</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- alternatively, if you prefer:
|
||||
--constant 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}}</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">verhoeff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">show_workings</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">validate</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Validation"</span><span style="color: #0000FF;">}:{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">&</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Check digit"</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">show_workings</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s calculations for `%s`:\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" i ni p(i,ni) c\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"------------------\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ni</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">ni</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">show_workings</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2d %d %d %d\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ni</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pi</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">inv</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #008000;">'0'</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">validate</span><span style="color: #0000FF;">?</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"in"</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"correct"</span>
|
||||
<span style="color: #0000FF;">:</span><span style="color: #008000;">"`"</span><span style="color: #0000FF;">&</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"`"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The %s for `%s` is %s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">),</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">ch</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"236"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"12345"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"123456789012"</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">show_workings</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">verhoeff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">show_workings</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">verhoeff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">show_workings</span><span style="color: #0000FF;">)==</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">verhoeff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">'9'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">show_workings</span><span style="color: #0000FF;">)!=</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
59
Task/Verhoeff-algorithm/Python/verhoeff-algorithm.py
Normal file
59
Task/Verhoeff-algorithm/Python/verhoeff-algorithm.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
MULTIPLICATION_TABLE = [
|
||||
(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)
|
||||
|
||||
PERMUTATION_TABLE = [
|
||||
(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),
|
||||
]
|
||||
|
||||
def verhoeffchecksum(n, validate=True, terse=True, verbose=False):
|
||||
"""
|
||||
Calculate the Verhoeff checksum over `n`.
|
||||
Terse mode or with single argument: return True if valid (last digit is a correct check digit).
|
||||
If checksum mode, return the expected correct checksum digit.
|
||||
If validation mode, return True if last digit checks correctly.
|
||||
"""
|
||||
if verbose:
|
||||
print(f"\n{'Validation' if validate else 'Check digit'}",\
|
||||
f"calculations for {n}:\n\n i nᵢ p[i,nᵢ] c\n------------------")
|
||||
# transform number list
|
||||
c, dig = 0, list(str(n if validate else 10 * n))
|
||||
for i, ni in enumerate(dig[::-1]):
|
||||
p = PERMUTATION_TABLE[i % 8][int(ni)]
|
||||
c = MULTIPLICATION_TABLE[c][p]
|
||||
if verbose:
|
||||
print(f"{i:2} {ni} {p} {c}")
|
||||
|
||||
if verbose and not validate:
|
||||
print(f"\ninv({c}) = {INV[c]}")
|
||||
if not terse:
|
||||
print(f"\nThe validation for '{n}' is {'correct' if c == 0 else 'incorrect'}."\
|
||||
if validate else f"\nThe check digit for '{n}' is {INV[c]}.")
|
||||
return c == 0 if validate else INV[c]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
for n, va, t, ve in [
|
||||
(236, False, False, True), (2363, True, False, True), (2369, True, False, True),
|
||||
(12345, False, False, True), (123451, True, False, True), (123459, True, False, True),
|
||||
(123456789012, False, False, False), (1234567890120, True, False, False),
|
||||
(1234567890129, True, False, False)]:
|
||||
verhoeffchecksum(n, va, t, ve)
|
||||
47
Task/Verhoeff-algorithm/Raku/verhoeff-algorithm.raku
Normal file
47
Task/Verhoeff-algorithm/Raku/verhoeff-algorithm.raku
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
my @d = [^10] xx 5;
|
||||
@d[$_][^5].=rotate($_), @d[$_][5..*].=rotate($_) for 1..4;
|
||||
push @d: [@d[$_].reverse] for flat 1..4, 0;
|
||||
|
||||
my @i = 0,4,3,2,1,5,6,7,8,9;
|
||||
|
||||
my %h = flat (0,1,5,8,9,4,2,7,0).rotor(2 =>-1).map({.[0]=>.[1]}), 6=>3, 3=>6;
|
||||
my @p = [^10],;
|
||||
@p.push: [@p[*-1].map: {%h{$_}}] for ^7;
|
||||
|
||||
sub checksum (Int $int where * ≥ 0, :$verbose = True ) {
|
||||
my @digits = $int.comb;
|
||||
say "\nCheckdigit calculation for $int:";
|
||||
say " i ni p(i, ni) c" if $verbose;
|
||||
my ($i, $p, $c) = 0 xx 3;
|
||||
say " $i 0 $p $c" if $verbose;
|
||||
for @digits.reverse {
|
||||
++$i;
|
||||
$p = @p[$i % 8][$_];
|
||||
$c = @d[$c; $p];
|
||||
say "{$i.fmt('%2d')} $_ $p $c" if $verbose;
|
||||
}
|
||||
say "Checkdigit: {@i[$c]}";
|
||||
+($int ~ @i[$c]);
|
||||
}
|
||||
|
||||
sub validate (Int $int where * ≥ 0, :$verbose = True) {
|
||||
my @digits = $int.comb;
|
||||
say "\nValidation calculation for $int:";
|
||||
say " i ni p(i, ni) c" if $verbose;
|
||||
my ($i, $p, $c) = 0 xx 3;
|
||||
for @digits.reverse {
|
||||
$p = @p[$i % 8][$_];
|
||||
$c = @d[$c; $p];
|
||||
say "{$i.fmt('%2d')} $_ $p $c" if $verbose;
|
||||
++$i;
|
||||
}
|
||||
say "Checkdigit: {'in' if $c}correct";
|
||||
}
|
||||
|
||||
## TESTING
|
||||
|
||||
for 236, 12345, 123456789012 -> $int {
|
||||
my $check = checksum $int, :verbose( $int.chars < 8 );
|
||||
validate $check, :verbose( $int.chars < 8 );
|
||||
validate +($check.chop ~ 9), :verbose( $int.chars < 8 );
|
||||
}
|
||||
75
Task/Verhoeff-algorithm/V-(Vlang)/verhoeff-algorithm.v
Normal file
75
Task/Verhoeff-algorithm/V-(Vlang)/verhoeff-algorithm.v
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
const 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],
|
||||
]
|
||||
|
||||
const inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
|
||||
|
||||
const 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],
|
||||
]
|
||||
|
||||
fn verhoeff(ss string, validate bool, table bool) int {
|
||||
mut s:= ss
|
||||
if table {
|
||||
mut t := "Check digit"
|
||||
if validate {
|
||||
t = "Validation"
|
||||
}
|
||||
println("$t calculations for '$s':\n")
|
||||
println(" i nᵢ p[i,nᵢ] c")
|
||||
println("------------------")
|
||||
}
|
||||
if !validate {
|
||||
s = s + "0"
|
||||
}
|
||||
mut c := 0
|
||||
le := s.len - 1
|
||||
for i := le; i >= 0; i-- {
|
||||
ni := int(s[i] - 48)
|
||||
pi := p[(le-i)%8][ni]
|
||||
c = d[c][pi]
|
||||
if table {
|
||||
println("${le-i:2} $ni $pi $c")
|
||||
}
|
||||
}
|
||||
if table && !validate {
|
||||
println("\ninv[$c] = ${inv[c]}")
|
||||
}
|
||||
if !validate {
|
||||
return inv[c]
|
||||
}
|
||||
return int(c == 0)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
ss := ["236", "12345", "123456789012"]
|
||||
ts := [true, true, false, true]
|
||||
for i, s in ss {
|
||||
c := verhoeff(s, false, ts[i])
|
||||
println("\nThe check digit for '$s' is '$c'\n")
|
||||
for sc in [s + c.str(), s + "9"] {
|
||||
v := verhoeff(sc, true, ts[i])
|
||||
mut ans := "correct"
|
||||
if v==0 {
|
||||
ans = "incorrect"
|
||||
}
|
||||
println("\nThe validation for '$sc' is $ans\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Task/Verhoeff-algorithm/Wren/verhoeff-algorithm.wren
Normal file
56
Task/Verhoeff-algorithm/Wren/verhoeff-algorithm.wren
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import "/fmt" for Fmt
|
||||
|
||||
var 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]
|
||||
]
|
||||
|
||||
var inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
|
||||
|
||||
var 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]
|
||||
]
|
||||
|
||||
var verhoeff = Fn.new { |s, validate, table|
|
||||
if (table) {
|
||||
System.print("%(validate ? "Validation" : "Check digit") calculations for '%(s)':\n")
|
||||
System.print(" i nᵢ p[i,nᵢ] c")
|
||||
System.print("------------------")
|
||||
}
|
||||
if (!validate) s = s + "0"
|
||||
var c = 0
|
||||
var le = s.count - 1
|
||||
for (i in le..0) {
|
||||
var ni = s[i].bytes[0] - 48
|
||||
var pi = p[(le-i) % 8][ni]
|
||||
c = d[c][pi]
|
||||
if (table) Fmt.print("$2d $d $d $d", le-i, ni, pi, c)
|
||||
}
|
||||
if (table && !validate) System.print("\ninv[%(c)] = %(inv[c])")
|
||||
return !validate ? inv[c] : c == 0
|
||||
}
|
||||
|
||||
var sts = [["236", true], ["12345", true], ["123456789012", false]]
|
||||
for (st in sts) {
|
||||
var c = verhoeff.call(st[0], false, st[1])
|
||||
System.print("\nThe check digit for '%(st[0])' is '%(c)'\n")
|
||||
for (stc in [st[0] + c.toString, st[0] + "9"]) {
|
||||
var v = verhoeff.call(stc, true, st[1])
|
||||
System.print("\nThe validation for '%(stc)' is %(v ? "correct" : "incorrect").\n")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue