62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
const (
|
||
letters = 26
|
||
numbers = 900 // 100–999
|
||
block = letters * letters * letters * numbers // 26^3 * 900
|
||
)
|
||
|
||
func Encode(code string) (uint32, error) {
|
||
// Verwacht formaat: L1L2-NNN-L3-C => lengte 10, posities: 0,1,3,4,5,7,9
|
||
if len(code) != 10 || code[2] != '-' || code[6] != '-' || code[8] != '-' {
|
||
return 0, errors.New("invalid format, expected LL-NNN-L-C")
|
||
}
|
||
|
||
l1, l2, l3 := code[0], code[1], code[7]
|
||
|
||
// letters checken
|
||
// forbidden alleen op l1,l2
|
||
// nummer parsen uit code[3:6]
|
||
|
||
L1 := int(l1 - 'A')
|
||
L2 := int(l2 - 'A')
|
||
L3 := int(l3 - 'A')
|
||
N := num - 100
|
||
|
||
idx := uint32((((L1*letters + L2)*letters + L3) * numbers) + N)
|
||
|
||
if code[9] != checksumLetter(idx) {
|
||
return 0, errors.New("invalid checksum")
|
||
}
|
||
|
||
return idx, nil
|
||
}
|
||
|
||
func Decode(idx uint32) (string, error) {
|
||
if idx >= block {
|
||
return "", errors.New("index out of range")
|
||
}
|
||
|
||
x := int(idx)
|
||
|
||
L1 := x / (letters * letters * numbers)
|
||
r1 := x % (letters * letters * numbers)
|
||
|
||
L2 := r1 / (letters * numbers)
|
||
r2 := r1 % (letters * numbers)
|
||
|
||
L3 := r2 / numbers
|
||
N := r2 % numbers
|
||
|
||
l1 := byte('A' + L1)
|
||
l2 := byte('A' + L2)
|
||
l3 := byte('A' + L3)
|
||
|
||
if isForbiddenPair(l1, l2) {
|
||
return "", errors.New("forbidden letter combination")
|
||
}
|
||
|
||
c := checksumLetter(idx)
|
||
|
||
return fmt.Sprintf("%c%c-%03d-%c-%c", l1, l2, N+100, l3, c), nil
|
||
}
|
||
|