Verhoeff algorithm: Difference between revisions
Content added Content deleted
(Added Go) |
|||
Line 104: | Line 104: | ||
Identical to Wren example |
Identical to Wren example |
||
</pre> |
</pre> |
||
=={{header|Nim}}== |
|||
<lang Nim>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()</lang> |
|||
{{out}} |
|||
<pre>Check digit computation for 236: |
|||
i ni p(i, ni) c |
|||
0 0 0 0 |
|||
1 6 3 3 |
|||
2 3 3 1 |
|||
3 2 1 2 |
|||
The check digit for 236 is 3. |
|||
Check digit validation for 2363: |
|||
i ni p(i, ni) c |
|||
0 3 3 3 |
|||
1 6 3 1 |
|||
2 3 3 4 |
|||
3 2 1 0 |
|||
Validation is successful. |
|||
Check digit validation for 2369: |
|||
i ni p(i, ni) c |
|||
0 9 9 9 |
|||
1 6 3 6 |
|||
2 3 3 8 |
|||
3 2 1 7 |
|||
Validation is not successful. |
|||
Check digit computation for 12345: |
|||
i ni p(i, 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 |
|||
The check digit for 12345 is 1. |
|||
Check digit validation for 123451: |
|||
i ni p(i, ni) c |
|||
0 1 1 1 |
|||
1 5 8 9 |
|||
2 4 7 2 |
|||
3 3 6 8 |
|||
4 2 5 3 |
|||
5 1 2 0 |
|||
Validation is successful. |
|||
Check digit validation for 123459: |
|||
i ni p(i, ni) c |
|||
0 9 9 9 |
|||
1 5 8 1 |
|||
2 4 7 8 |
|||
3 3 6 2 |
|||
4 2 5 7 |
|||
5 1 2 5 |
|||
Validation is not successful. |
|||
Check digit for 123456789012 is 0. |
|||
Check digit validation was successful for 1234567890120. |
|||
Check digit validation failed for 1234567890129.</pre> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |