-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhkidchecker.go
75 lines (65 loc) · 1.76 KB
/
hkidchecker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// hkidchecker checks if a Hong Kong ID number is valid or not
package hkidchecker
import (
"regexp"
"strconv"
"strings"
)
// Validation is implemented as described on this page:
// https://computerterminal.blogspot.com/2013/02/hong-kong-id-formula-hkid-number-check.html
var hkidRegExp *regexp.Regexp
const hkidMaxLen = 11
const hkidDataLen = 8
func init() {
hkidRegExp = regexp.MustCompile(`^[A-Z]{1,2}[0-9]{6}\([0-9A]{1}\)$`)
}
// CheckHKIDFormat checks the format of a Hong Kong ID without calculating
// and checking the checksum
func CheckHKIDFormat(hkid string) bool {
return hkidRegExp.MatchString(strings.TrimSpace(hkid))
}
// CheckHKID checks the format and validates the checksum of a Hong Kong ID
func CheckHKID(hkid string) bool {
hkid = strings.TrimSpace(hkid)
if !CheckHKIDFormat(hkid) {
// HKID is not matching the basic format check
return false
}
if len(hkid) != hkidMaxLen {
// If only one letter is used in the beginning, add a padding space
// otherwise the calculation will not work
hkid = " " + hkid
}
checkDigit := hkid[hkidDataLen:][1:2]
sum := 0
for i := 0; i < hkidDataLen; i++ {
var num int
ch := hkid[i]
if ch == ' ' {
// Space = 36
num = 36
} else if ch >= '0' && ch <= '9' {
// 0-9 = 0-9
num = int(hkid[i] - '0')
} else {
// A-Z = 10-35
num = int(hkid[i]-'A') + 10
}
// Each char num is multiplied with a number starting with 9 and
// decreasing for each position down to 2
sum += num * ((hkidDataLen + 1) - i)
}
var calcCheck string
const modulo = 11
remainder := sum % modulo
if remainder == 0 {
// Special case 0
calcCheck = "0"
} else if remainder == 1 {
// Special case A
calcCheck = "A"
} else {
calcCheck = strconv.Itoa(modulo - remainder)
}
return calcCheck == checkDigit
}