lib/protocol: faster Luhn algorithm and better testing (#6475)

The previous implementation was very generic; its tests didn't cover the
actual alphabet for device IDs.

Benchmark results on amd64:

name         old time/op    new time/op     delta
Luhnify-8      1.00µs ± 1%     0.28µs ± 4%   -72.38%  (p=0.000 n=9+10)
Unluhnify-8     992ns ± 2%      274ns ± 1%   -72.39%  (p=0.000 n=10+9)
This commit is contained in:
greatroar
2020-03-29 22:28:04 +02:00
committed by GitHub
parent ea5c9176e1
commit 1e2379df1b
3 changed files with 29 additions and 60 deletions
+8 -30
View File
@@ -3,46 +3,24 @@
package protocol
import (
"strings"
"testing"
)
func TestGenerate(t *testing.T) {
// Base 6 Luhn
a := luhnAlphabet("abcdef")
c, err := a.generate("abcdef")
func TestLuhn32(t *testing.T) {
c, err := luhn32("AB725E4GHIQPL3ZFGT")
if err != nil {
t.Fatal(err)
}
if c != 'e' {
t.Errorf("Incorrect check digit %c != e", c)
if c != 'G' {
t.Errorf("Incorrect check digit %c != G", c)
}
// Base 10 Luhn
a = luhnAlphabet("0123456789")
c, err = a.generate("7992739871")
if err != nil {
t.Fatal(err)
}
if c != '3' {
t.Errorf("Incorrect check digit %c != 3", c)
}
}
func TestInvalidString(t *testing.T) {
a := luhnAlphabet("ABC")
_, err := a.generate("7992739871")
t.Log(err)
_, err = luhn32("3734EJEKMRHWPZQTWYQ1")
if err == nil {
t.Error("Unexpected nil error")
}
}
func TestValidate(t *testing.T) {
a := luhnAlphabet("abcdef")
if !a.luhnValidate("abcdefe") {
t.Errorf("Incorrect validation response for abcdefe")
}
if a.luhnValidate("abcdefd") {
t.Errorf("Incorrect validation response for abcdefd")
if !strings.Contains(err.Error(), "'1'") {
t.Errorf("luhn32 should have errored on digit '1', got %v", err)
}
}