Finish IsValid
method
This commit is contained in:
parent
e925273ff4
commit
e70138664f
32
Generator.go
Normal file
32
Generator.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package id_validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GeneratorCheckBit(body string) string {
|
||||||
|
// 位置加权
|
||||||
|
var posWeight [19]float64
|
||||||
|
for i := 2; i < 19; i++ {
|
||||||
|
weight := int(math.Pow(2, float64(i-1))) % 11
|
||||||
|
posWeight[i] = float64(weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 累身份证号 body 部分与位置加权的积
|
||||||
|
bodySum := 0
|
||||||
|
bodyArray := strings.Split(body, "")
|
||||||
|
count := len(bodyArray)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
bodySubStr, _ := strconv.Atoi(bodyArray[i])
|
||||||
|
bodySum += bodySubStr * int(posWeight[18-i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成校验码
|
||||||
|
checkBit := (12 - (bodySum % 11)) % 11
|
||||||
|
if checkBit == 10 {
|
||||||
|
return "X"
|
||||||
|
}
|
||||||
|
return strconv.Itoa(checkBit)
|
||||||
|
}
|
87
checker.go
Normal file
87
checker.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package id_validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 检查ID参数
|
||||||
|
func CheckIdArgument(id string) bool {
|
||||||
|
return len(GenerateType(id)) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成数据
|
||||||
|
func GenerateType(id string) map[string]string {
|
||||||
|
lowerId := strings.ToLower(id)
|
||||||
|
|
||||||
|
if len(lowerId) == 15 {
|
||||||
|
return GenerateShortType(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lowerId) == 18 {
|
||||||
|
return GenerateLongType(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成短数据
|
||||||
|
func GenerateShortType(id string) map[string]string {
|
||||||
|
mustCompile := regexp.MustCompile("(.{6})(.{6})(.{3})")
|
||||||
|
subMatch := mustCompile.FindStringSubmatch(id)
|
||||||
|
|
||||||
|
return map[string]string{
|
||||||
|
"body": subMatch[0],
|
||||||
|
"addressCode": subMatch[1],
|
||||||
|
"birthdayCode": "19" + subMatch[2],
|
||||||
|
"order": subMatch[3],
|
||||||
|
"checkBit": "",
|
||||||
|
"type": "15",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成长数据
|
||||||
|
func GenerateLongType(id string) map[string]string {
|
||||||
|
mustCompile := regexp.MustCompile("((.{6})(.{8})(.{3}))(.)")
|
||||||
|
subMatch := mustCompile.FindStringSubmatch(id)
|
||||||
|
|
||||||
|
return map[string]string{
|
||||||
|
"body": subMatch[1],
|
||||||
|
"addressCode": subMatch[2],
|
||||||
|
"birthdayCode": subMatch[3],
|
||||||
|
"order": subMatch[4],
|
||||||
|
"checkBit": subMatch[5],
|
||||||
|
"type": "18",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查地址码
|
||||||
|
func CheckAddressCode(addressCode string, birthdayCode string) bool {
|
||||||
|
addressInfo := GetAddressInfo(addressCode, birthdayCode)
|
||||||
|
if addressInfo["province"] == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查出生日期码
|
||||||
|
func CheckBirthdayCode(birthdayCode string) bool {
|
||||||
|
year, _ := strconv.Atoi(Substr(birthdayCode, 0, 4))
|
||||||
|
if year < 1800 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
_, error := time.Parse("20060102", birthdayCode)
|
||||||
|
if error != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查顺序码
|
||||||
|
func CheckOrderCode(orderCode string) bool {
|
||||||
|
return len(orderCode) == 3
|
||||||
|
}
|
6424
data/address_code.go
6424
data/address_code.go
File diff suppressed because it is too large
Load Diff
75
helper.go
Normal file
75
helper.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package id_validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"id-validator/data"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 检查地址码
|
||||||
|
func GetAddressInfo(addressCode string, birthdayCode string) map[string]string {
|
||||||
|
addressInfo := map[string]string{
|
||||||
|
"province": "",
|
||||||
|
"city": "",
|
||||||
|
"district": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
// 省级信息
|
||||||
|
provinceAddressCode := Substr(addressCode, 0, 2) + "0000"
|
||||||
|
addressInfo["province"] = GetAddress(provinceAddressCode, birthdayCode)
|
||||||
|
|
||||||
|
// 用于判断是否是港澳台居民居住证(8字开头)
|
||||||
|
firstCharacter := Substr(addressCode, 0, 1)
|
||||||
|
// 港澳台居民居住证无市级、县级信息
|
||||||
|
if firstCharacter == "8" {
|
||||||
|
return addressInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// 市级信息
|
||||||
|
cityAddressCode := Substr(addressCode, 0, 4) + "00"
|
||||||
|
addressInfo["city"] = GetAddress(cityAddressCode, birthdayCode)
|
||||||
|
|
||||||
|
// 县级信息
|
||||||
|
addressInfo["district"] = GetAddress(addressCode, birthdayCode)
|
||||||
|
|
||||||
|
return addressInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAddress(addressCode string, birthdayCode string) string {
|
||||||
|
var address string
|
||||||
|
|
||||||
|
addressCodeStr, _ := strconv.Atoi(addressCode)
|
||||||
|
addressCodeTimeline := data.AddressCodeTimeline[addressCodeStr]
|
||||||
|
|
||||||
|
year := Substr(birthdayCode, 0, 4)
|
||||||
|
yearStr, _ := strconv.Atoi(year)
|
||||||
|
|
||||||
|
for key, val := range addressCodeTimeline {
|
||||||
|
if len(val) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
startYear, _ := strconv.Atoi(val["start_year"])
|
||||||
|
if (key == 0 && yearStr < startYear) || yearStr >= startYear {
|
||||||
|
address = val["address"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
|
||||||
|
// Substr 截取字符串
|
||||||
|
func Substr(source string, start int, end int) string {
|
||||||
|
var r = []rune(source)
|
||||||
|
length := len(r)
|
||||||
|
|
||||||
|
if start < 0 || end > length || start > end {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if start == 0 && end == length {
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(r[start:end])
|
||||||
|
}
|
23
id_validator.go
Normal file
23
id_validator.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package id_validator
|
||||||
|
|
||||||
|
// 验证身份证号合法性
|
||||||
|
func IsValid(id string) bool {
|
||||||
|
if !CheckIdArgument(id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
code := GenerateType(id)
|
||||||
|
if !CheckAddressCode(code["addressCode"], code["birthdayCode"]) || !CheckBirthdayCode(code["birthdayCode"]) || !CheckOrderCode(code["order"]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 15位身份证不含校验码
|
||||||
|
if code["type"] == "15" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证:校验码
|
||||||
|
checkBit := GeneratorCheckBit(code["body"])
|
||||||
|
|
||||||
|
return code["checkBit"] == checkBit
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user