Added CompleteCode function.
All checks were successful
CI / test (push) Successful in 17s

This commit is contained in:
2026-02-21 04:19:19 +01:00
parent 50e9036400
commit 22ca29b4af
5 changed files with 110 additions and 10 deletions

View File

@@ -19,15 +19,16 @@ const (
)
var (
ErrInvalidFormat = errors.New("invalid format, expected LLL-NNN-LC")
ErrInvalidLetters = errors.New("invalid letters")
ErrForbiddenLetterTriplet = errors.New("forbidden letter combination")
ErrInvalidNumber = errors.New("invalid number")
ErrNumberOutOfRange = errors.New("number out of range")
ErrInvalidChecksum = errors.New("invalid checksum")
ErrIndexOutOfRange = errors.New("index out of range")
ErrRandomSourceFailed = errors.New("random source failed")
ErrNoAvailableIndex = errors.New("no available index found")
ErrInvalidFormat = errors.New("invalid format, expected LLL-NNN-LC")
ErrInvalidFormatNoChecksum = errors.New("invalid format, expected LLL-NNN-L")
ErrInvalidLetters = errors.New("invalid letters")
ErrForbiddenLetterTriplet = errors.New("forbidden letter combination")
ErrInvalidNumber = errors.New("invalid number")
ErrNumberOutOfRange = errors.New("number out of range")
ErrInvalidChecksum = errors.New("invalid checksum")
ErrIndexOutOfRange = errors.New("index out of range")
ErrRandomSourceFailed = errors.New("random source failed")
ErrNoAvailableIndex = errors.New("no available index found")
)
type RandomCodeOptions struct {
@@ -112,6 +113,40 @@ func Decode(idx uint32) (string, error) {
return code, nil
}
func CompleteCode(codeWithoutChecksum string) (string, uint32, error) {
if len(codeWithoutChecksum) != 9 || codeWithoutChecksum[3] != '-' || codeWithoutChecksum[7] != '-' {
return "", 0, ErrInvalidFormatNoChecksum
}
l1, l2, l3, l4 := codeWithoutChecksum[0], codeWithoutChecksum[1], codeWithoutChecksum[2], codeWithoutChecksum[8]
n1, n2, n3 := codeWithoutChecksum[4], codeWithoutChecksum[5], codeWithoutChecksum[6]
if !isUpperAlphaASCII(l1) || !isUpperAlphaASCII(l2) || !isUpperAlphaASCII(l3) || !isUpperAlphaASCII(l4) {
return "", 0, ErrInvalidLetters
}
if IsForbiddenTriplet(l1, l2, l3) {
return "", 0, ErrForbiddenLetterTriplet
}
if !isNumber(n1) || !isNumber(n2) || !isNumber(n3) {
return "", 0, ErrInvalidNumber
}
L1 := uint32(l1 - 'A')
L2 := uint32(l2 - 'A')
L3 := uint32(l3 - 'A')
L4 := uint32(l4 - 'A')
num := uint32(n1-'0')*100 + uint32(n2-'0')*10 + uint32(n3-'0')
if num < 100 || num > 999 {
return "", 0, ErrNumberOutOfRange
}
N := num - 100
idx := uint32((((((L1*letters+L2)*letters+L3)*letters + L4) * numbers) + N))
checksum := checksumLetter(idx)
return codeWithoutChecksum + string(checksum), idx, nil
}
func RandomCode(isInUse ...func(uint32) bool) (string, uint32, error) {
options := RandomCodeOptions{}
if len(isInUse) > 0 {