-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
id_validator.go
158 lines (129 loc) · 3.87 KB
/
id_validator.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// This file is part of the guanguans/id-validator.
// (c) guanguans <[email protected]>
// This source file is subject to the MIT license that is bundled.
package idvalidator
import (
"errors"
"strconv"
"time"
"github.com/guanguans/id-validator/data"
"github.com/spf13/cast"
)
// IdInfo 身份证信息
type IdInfo struct {
AddressCode int
Abandoned int
Address string
AddressTree []string
Birthday time.Time
Constellation string
ChineseZodiac string
Sex int
Length int
CheckBit string
}
// IsValid 验证身份证号合法性
func IsValid(id string, strict bool) bool {
code, err := generateCode(id)
if err != nil {
return false
}
// 检查顺序码、生日码、地址码
if !checkOrderCode(code["order"]) || !checkBirthdayCode(code["birthdayCode"]) || !checkAddressCode(code["addressCode"], code["birthdayCode"], strict) {
return false
}
// 15位身份证不含校验码
if code["type"] == "15" {
return true
}
// 校验码
return code["checkBit"] == generatorCheckBit(code["body"])
}
// IsLooseValid 宽松验证身份证号合法性
func IsLooseValid(id string) bool {
return IsValid(id, false)
}
// IsStrictValid 严格验证身份证号合法性
func IsStrictValid(id string) bool {
return IsValid(id, true)
}
// GetInfo 获取身份证信息
func GetInfo(id string, strict bool) (IdInfo, error) {
// 验证有效性
if !IsValid(id, strict) {
return IdInfo{}, errors.New("invalid ID card number")
}
code, _ := generateCode(id)
addressCode := cast.ToUint32(code["addressCode"])
// 地址信息
addressInfo := getAddressInfo(code["addressCode"], code["birthdayCode"], strict)
addressTree := []string{addressInfo["province"], addressInfo["city"], addressInfo["district"]}
// 是否废弃
abandoned := 0
if data.AddressCode()[addressCode] == "" {
abandoned = 1
}
// 生日
cst, _ := time.LoadLocation("Asia/Shanghai")
birthday, _ := time.ParseInLocation("20060102", code["birthdayCode"], cst)
// 性别
sex := 1
order, _ := strconv.Atoi(code["order"])
if (order % 2) == 0 {
sex = 0
}
// 长度
length := cast.ToInt(code["type"])
return IdInfo{
AddressCode: int(addressCode),
Abandoned: abandoned,
Address: addressInfo["province"] + addressInfo["city"] + addressInfo["district"],
AddressTree: addressTree,
Birthday: birthday,
Constellation: getConstellation(code["birthdayCode"]),
ChineseZodiac: getChineseZodiac(code["birthdayCode"]),
Sex: sex,
Length: length,
CheckBit: code["checkBit"],
}, nil
}
// FakeId 生成假身份证号码
func FakeId() string {
return FakeRequireId(true, "", "", 0)
}
// FakeRequireId 按要求生成假身份证号码
// isEighteen 是否生成18位号码
// address 省市县三级地区官方全称:如`北京市`、`台湾省`、`香港特别行政区`、`深圳市`、`黄浦区`
// birthday 出生日期:如 `2000`、`198801`、`19990101`
// sex 性别:1为男性,0为女性
func FakeRequireId(isEighteen bool, address string, birthday string, sex int) string {
// 生成地址码
addressCode := ""
if address == "" {
for i, s := range data.AddressCode() {
addressCode = cast.ToString(i)
address = s
break
}
} else {
addressCode = generatorAddressCode(address)
}
// 出生日期码
birthdayCode := generatorBirthdayCode(addressCode, address, birthday)
// 生成顺序码
orderCode := generatorOrderCode(sex)
if !isEighteen {
return addressCode + substr(birthdayCode, 2, 8) + orderCode
}
body := addressCode + birthdayCode + orderCode
return body + generatorCheckBit(body)
}
// UpgradeId 15位升级18位号码
func UpgradeId(id string) (string, error) {
if !IsValid(id, true) {
return "", errors.New("invalid ID card number")
}
code, _ := generateShortCode(id)
body := code["addressCode"] + code["birthdayCode"] + code["order"]
return body + generatorCheckBit(body), nil
}