Skip to content

Commit

Permalink
Add hybrid check (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacoelho authored May 24, 2021
1 parent 894b519 commit 1d21fff
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 25 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ Pure systems:

Hybrid systems:

* `MOD 11-10`
* `MOD 27-26`
* `MOD 37-36`
| Designation | Input (string) | Output (string) |
| ----------- | -------------- | ----------------- |
| `MOD 11,10` | numeric | 1 digit |
| `MOD 27,26` | alphabetic | 1 letter |
| `MOD 37,36` | alpha numeric | 1 digit or letter |

## Credits

Expand Down
18 changes: 3 additions & 15 deletions iso7064/charsets.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ func numericToString(v int) string {
return digits[v : v+1]
}

func numericPlusXToValue(r rune) int {
if r == 'X' {
return 10
}
return int(r - '0')
}

func numericPlusXToString(v int) string {
return digitsPlusX[v : v+1]
}
Expand All @@ -35,16 +28,11 @@ func alphaToString(v int) string {
}

func alphanumericToValue(r rune) int {
switch {
case r == '*':
return 36

case r >= '0' && r <= '9':
if r >= '0' && r <= '9' {
return int(r - '0')

default:
return int(10 + r - 'A')
}

return int(10 + r - 'A')
}

func alphanumericToString(v int) string {
Expand Down
25 changes: 25 additions & 0 deletions iso7064/example_hybrid_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package iso7064_test

import (
"fmt"

"github.com/jacoelho/go-iso7064/iso7064"
)

func ExampleModulo1110() {
// Modulo1110
fmt.Println(iso7064.Modulo1110("4600034236774"))
// Output: 1
}

func ExampleModulo2726() {
// Modulo2726
fmt.Println(iso7064.Modulo2726("MUFEMSTCATLIT"))
// Output: B
}

func ExampleModulo3736() {
// Modulo3736
fmt.Println(iso7064.Modulo3736("B3739U6CR"))
// Output: K
}
36 changes: 36 additions & 0 deletions iso7064/hybrid.go
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
package iso7064

// hybrid system recursive method
func hybrid(modulo int, from fromAlphabet, to toAlphabet, input string) string {
sum := modulo
for _, r := range input {
intermediate := (sum + from(r)) % modulo

if intermediate == 0 {
intermediate = modulo
}

sum = (intermediate * 2) % (modulo + 1)
}

checksum := (1 + modulo - sum) % modulo

return to(checksum)
}

// Modulo1110 generates check character in accordance with ISO/IEC 7064, MOD 11,10
// Designation 6
func Modulo1110(input string) string {
return hybrid(10, numericToValue, numericToString, input)
}

// Modulo2726 generates check character in accordance with ISO/IEC 7064, MOD 27,26
// Designation 7
func Modulo2726(input string) string {
return hybrid(26, alphaToValue, alphaToString, input)
}

// Modulo3736 generates check character in accordance with ISO/IEC 7064, MOD 37,36
// Designation 8
func Modulo3736(input string) string {
return hybrid(36, alphanumericToValue, alphanumericToString, input)
}
45 changes: 45 additions & 0 deletions iso7064/modulo11_10_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package iso7064

import (
"testing"
)

func TestModulo11_10(t *testing.T) {
tests := []struct {
input string
want string
}{
{input: "079", want: "2"},
{input: "0794", want: "5"},
{input: "6511224300430482", want: "7"},
{input: "53266878780357001264776215687313785128868", want: "4"},
{input: "003", want: "2"},
{input: "7846306445607555258161616166", want: "2"},
{input: "861543053353545631188671371628487317133258177413", want: "0"},
{input: "4555773880", want: "8"},
{input: "05320162033", want: "8"},
{input: "71065204127183146616272676714658212652753", want: "4"},
{input: "4716", want: "6"},
{input: "68058451423857734108017363773364282850032", want: "1"},
{input: "4674678664653", want: "1"},
{input: "42328026", want: "0"},
{input: "500300224343584662684600506004225567445126724117", want: "5"},
{input: "65428072048156805364127530485864402163255", want: "9"},
{input: "308655184386", want: "3"},
{input: "4317754156343048540758528678637685134", want: "4"},
{input: "4600034236774", want: "1"},
{input: "1385812104511745558672550524138724810", want: "9"},
{input: "1563104756864506624875436082452546036618466424", want: "6"},
{input: "71660618558507745431171460", want: "5"},
{input: "3676012560274058125725682603573122447174631135", want: "4"},
{input: "853", want: "7"},
}
for _, tt := range tests {
tt := tt
t.Run(tt.input, func(t *testing.T) {
if got := Modulo1110(tt.input); got != tt.want {
t.Errorf("Modulo1110() = %v, want %v", got, tt.want)
}
})
}
}
25 changes: 25 additions & 0 deletions iso7064/modulo27_26_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package iso7064

import (
"testing"
)

func TestModulo27_26(t *testing.T) {
tests := []struct {
input string
want string
}{
{input: "JEJLMGJ", want: "S"},
{input: "MUFEMSTCATLIT", want: "B"},
{input: "VAQKBDHZQDYVZIATTNETJULCDAVRMQIEKIBD", want: "D"},
{input: "OWNYDSZNWIBFVBRWRA", want: "U"},
}
for _, tt := range tests {
tt := tt
t.Run(tt.input, func(t *testing.T) {
if got := Modulo2726(tt.input); got != tt.want {
t.Errorf("Modulo2726() = %v, want %v", got, tt.want)
}
})
}
}
42 changes: 42 additions & 0 deletions iso7064/modulo37_36_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package iso7064

import (
"testing"
)

func TestModulo37_36(t *testing.T) {
tests := []struct {
input string
want string
}{
{input: "A12425GABC1234002", want: "M"},
{input: "RABD", want: "A"},
{input: "X0H", want: "X"},
{input: "B7Q3SFTUSH2QN7BIXBPMNZAM", want: "I"},
{input: "UFSYYJO9FCID766EJYAEINTG43UZDD84MT6ZUDH08OM4N1K", want: "N"},
{input: "ROYL38YZ9TDGPNB5MT40CEWGURAOKF07XEYTV3M", want: "6"},
{input: "TBR", want: "1"},
{input: "EFWW032G2TI", want: "U"},
{input: "9", want: "J"},
{input: "B3739U6CR", want: "K"},
{input: "H0DJFUS8HHGZNEE9H6ZWW", want: "O"},
{input: "C8AWF5G0CE8U9VTKSPPS2JAP09ZFEGFEAV", want: "L"},
{input: "OW", want: "N"},
{input: "TRO", want: "D"},
{input: "1M", want: "Q"},
{input: "FLFOWRIBFCNWNMNFVKAJVS7REUS2L", want: "2"},
{input: "7LI6P5WTF2JHU", want: "U"},
{input: "KUHNOF8OA1NXCW", want: "A"},
{input: "KV0MFQXMAL4W5ICNH", want: "P"},
{input: "MM61BF7H6C2O86NNMW8ZY8V", want: "8"},
{input: "WP8Z0", want: "9"},
}
for _, tt := range tests {
tt := tt
t.Run(tt.input, func(t *testing.T) {
if got := Modulo3736(tt.input); got != tt.want {
t.Errorf("Modulo3736() = %v, want %v", got, tt.want)
}
})
}
}
16 changes: 9 additions & 7 deletions iso7064/pure.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ type (

// pure system recursive method
// multiples of the modulo are discarded
func pure(modulus, radix int, doubleChecksum bool, from fromAlphabet, to toAlphabet, input string) string {
func pure(modulo, radix int, doubleCharacterChecksum bool, from fromAlphabet, to toAlphabet, input string) string {
var sum int
for _, r := range input {
intermediate := (sum + from(r)) * radix
sum = intermediate % modulus // discard modulus multiples
sum = intermediate % modulo // discard modulo multiples
}

if doubleChecksum {
sum = (sum * radix) % modulus
// compute once more if double character checksum
// equivalent to suffix the initial value from the respective alphabet
if doubleCharacterChecksum {
sum = (sum * radix) % modulo
}

checksum := (1 + modulus - sum) % modulus
checksum := (1 + modulo - sum) % modulo

if !doubleChecksum {
if !doubleCharacterChecksum {
return to(checksum)
}

Expand All @@ -33,7 +35,7 @@ func pure(modulus, radix int, doubleChecksum bool, from fromAlphabet, to toAlpha
// Modulo11Radix2 generates check character in accordance with ISO/IEC 7064, MOD 11–2
// Designation 1
func Modulo11Radix2(input string) string {
return pure(11, 2, false, numericPlusXToValue, numericPlusXToString, input)
return pure(11, 2, false, numericToValue, numericPlusXToString, input)
}

// Modulo37Radix2 generates check character in accordance with ISO/IEC 7064, MOD 37–2
Expand Down

0 comments on commit 1d21fff

Please sign in to comment.