Skip to content

Commit

Permalink
Add normalise functions (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacoelho authored May 24, 2021
1 parent cb19f88 commit 894b519
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 2 deletions.
80 changes: 80 additions & 0 deletions iso7064/normalise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package iso7064

import (
"strings"
)

// copied from utf8 package
// characters below runeSelf are represented as themselves in a single byte.
const runeSelf = 0x80

func isNumeric(b uint8) bool {
return '0' <= b && b <= '9'
}

func isAlphabeticUppercase(b uint8) bool {
return 'A' <= b && b <= 'Z'
}

func isAlphabeticLowercase(b uint8) bool {
return 'a' <= b && b <= 'z'
}

func isAlphabetic(b uint8) bool {
return isAlphabeticUppercase(b) || isAlphabeticLowercase(b)
}
func isAlphaNumeric(b uint8) bool {
return isNumeric(b) || isAlphabeticUppercase(b) || isAlphabeticLowercase(b)
}

func alphabeticLowerToUpper(b uint8) uint8 {
return b - 'a' + 'A'
}

func identity(c uint8) uint8 { return c }

func convertToUpper(c uint8) uint8 {
if !isAlphabeticLowercase(c) {
return c
}

return alphabeticLowerToUpper(c)
}

func normalise(predicate func(uint8) bool, convert func(uint8) uint8, input string) string {
sb := new(strings.Builder)

for i := 0; i < len(input); i++ {
c := input[i]

if c >= runeSelf {
continue
}

if predicate(c) {
sb.WriteByte(convert(c))
}
}

return sb.String()
}

// NormaliseNumeric filters a string ignoring non digit characters
// "1A3 4" is converted to "134"
func NormaliseNumeric(input string) string {
return normalise(isNumeric, identity, input)
}

// NormaliseAlphabetic filters a string ignoring non ascii letters characters
// lower case ascii letters are converted to uppercase
// "aB1c" is converted to "ABC"
func NormaliseAlphabetic(input string) string {
return normalise(isAlphabetic, convertToUpper, input)
}

// NormaliseAlphaNumeric filters a string ignoring non ascii letters or digit characters
// lower case ascii letters are converted to uppercase
// "aB1 c" is converted to "AB1C"
func NormaliseAlphaNumeric(input string) string {
return normalise(isAlphaNumeric, convertToUpper, input)
}
120 changes: 120 additions & 0 deletions iso7064/normalise_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package iso7064

import (
"testing"
)

func TestNormaliseNumeric(t *testing.T) {
tests := []struct {
input string
want string
}{
{
input: "0123456789",
want: "0123456789",
},
{
input: "012 345 678 9",
want: "0123456789",
},
{
input: "A012-345-678-9C",
want: "0123456789",
},
{
input: "ABCD",
want: "",
},
{
input: "A012-345-678-9C 🍔",
want: "0123456789",
},
}
for _, tt := range tests {
tt := tt

t.Run(tt.input, func(t *testing.T) {
if got := NormaliseNumeric(tt.input); got != tt.want {
t.Errorf("NormaliseNumeric() = %v, want %v", got, tt.want)
}
})
}
}

func TestNormaliseAlphabetic(t *testing.T) {
tests := []struct {
input string
want string
}{
{
input: "0123456789",
want: "",
},
{
input: "ABCD",
want: "ABCD",
},
{
input: "abcd",
want: "ABCD",
},
{
input: "a-b-c-d 🍔",
want: "ABCD",
},
{
input: "abcd123",
want: "ABCD",
},
}
for _, tt := range tests {
tt := tt

t.Run(tt.input, func(t *testing.T) {
if got := NormaliseAlphabetic(tt.input); got != tt.want {
t.Errorf("NormaliseAlphabetic() = %v, want %v", got, tt.want)
}
})
}
}

func TestNormaliseAlphaNumeric(t *testing.T) {
tests := []struct {
input string
want string
}{
{
input: "0123456789",
want: "0123456789",
},
{
input: "ABCD",
want: "ABCD",
},
{
input: "abcd",
want: "ABCD",
},
{
input: "a-b-c-d 🍔",
want: "ABCD",
},
{
input: "abcd123",
want: "ABCD123",
},
{
input: "aB1 c",
want: "AB1C",
},
}
for _, tt := range tests {
tt := tt

t.Run(tt.input, func(t *testing.T) {
if got := NormaliseAlphaNumeric(tt.input); got != tt.want {
t.Errorf("NormaliseAlphaNumeric() = %v, want %v", got, tt.want)
}
})
}
}
3 changes: 1 addition & 2 deletions iso7064/pure.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ type (
func pure(modulus, radix int, doubleChecksum bool, from fromAlphabet, to toAlphabet, input string) string {
var sum int
for _, r := range input {
v := from(r)
intermediate := (sum + v) * radix
intermediate := (sum + from(r)) * radix
sum = intermediate % modulus // discard modulus multiples
}

Expand Down

0 comments on commit 894b519

Please sign in to comment.