Skip to content

Commit

Permalink
Refactor check digit calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
mrclmr committed Jul 23, 2024
1 parent 45ceb38 commit a3a5bf3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
40 changes: 25 additions & 15 deletions cont/check_digit.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
package cont

// CalcCheckDigit calculates check digit for owner, equipment category ID and serial number.
// This function was optimized for fun and has a suboptimal reading experience.
func CalcCheckDigit(ownerCode string, equipCatID rune, serialNum int) int {
n := 0
d := 1
var n uint16 = 0

Check failure on line 6 in cont/check_digit.go

View workflow job for this annotation

GitHub Actions / build

var-declaration: should drop = 0 from declaration of var n; it is the zero value (revive)
var d uint16 = 1

for _, c := range ownerCode {
n += d * charValue(c)
n += d * charValue(uint16(c))
d *= 2
}
n += d * charValue(equipCatID)
d *= 2
divider := 100000
for divider > 0 {
n += d * ((serialNum / divider) % 10)
d *= 2
divider /= 10

n += d * charValue(uint16(equipCatID))

// Handle the case for the serial number when it is
// out of range of uint16.
n += 512 * uint16(serialNum%10)
serialNum /= 10
n += 256 * uint16(serialNum%10)

// uint16 can be used because we are now <10000
s := uint16(serialNum / 10)
d = 128
for d >= 16 {
n += d * (s % 10)
d /= 2
s /= 10
}
return n % 11
return int(n % 11)
}

// charValue returns the index of character plus 10.
// A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ
// A=10, B=12, C=13, ... , K=21, L=23, ...
func charValue(char rune) int {
n := int(char)
return n - 55 + (n-56)/10
// A=10, (no 11) B=12, C=13, ... , K=21, (no 22) L=23, ...
func charValue(char uint16) uint16 {
return char - 55 + (char-56)/10
}
5 changes: 5 additions & 0 deletions cont/check_digit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ func TestCalcCheckDigit(t *testing.T) {
args{"CSQ", 'U', 305438},
3,
},
{
"Test CSQ U 999998 3",
args{"CSQ", 'U', 999998},
3,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit a3a5bf3

Please sign in to comment.