Golang 实现本地身份证归属地查询
1)身份证号码验证
因为离线本地查询,不调用api接口,个人认为除了拥有公安机关保密的全国身份证号码数据库,要不然我们难以验证所有身份证号码是否正确。所以我们只能验证身份证格式,有些符合格式但是却又不存在的身份证号码可能也会被识别出来。我们主要从区域码、校验码和生日格式来判断身份证号码的准确性。
- 验证区域码
区域码就是身份证前两位数字,如:44代表广东省,45代表广西壮族自治区…
//验证区域码
func CheckProvinceValid(idcard string) bool {
citizenNo := []byte(idcard)
provinceCode := make([]byte, 0)
provinceCode = append(provinceCode, citizenNo[:2]...)
provinceStr := string(provinceCode)
for i, _ := range validProvince {
if provinceStr == validProvince[i] {
fmt.Println("区域码验证成功")
return true
}
}
fmt.Println("区域码验证失败")
return false
}
- 验证校验码
校验码就是18位身份证最后一位,通过特定的公式计算得到的,这里不做解释了。
//18位身份证校验码
func IsValidCitizenNo18(idcard string) bool {
//string -> []byte
citizenNo18 :=[]byte(idcard )
nSum := 0
for i := 0; i < len(citizenNo18) - 1; i++ {
n, _ := strconv.Atoi(string(citizenNo18[i]))
nSum += n * weight[i]
}
//mod得出18位身份证校验码
mod := nSum % 11
if validValue[mod] == citizenNo18[17] {
fmt.Println("校验码验证成功")
return true
}
fmt.Println("校验码验证失败")
return false
}
- 验证生日格式
//验证生日
func CheckBirthdayValid(nYear, nMonth, nDay int) bool {
if nYear < 1900 || nMonth <= 0 || nMonth > 12 || nDay <= 0 || nDay > 31 {
fmt.Println("生日验证失败")
return false
}
//出生日期大于现在的日期
curYear, curMonth, curDay := time.Now().Date()
if nYear == curYear {
if nMonth > int(curMonth) {
fmt.Println("生日验证失败")
return false
} else if nMonth == int(curMonth) && nDay > curDay {
fmt.Println("生日验证失败")
return false
}
}
//出生日期在2月份
if 2 == nMonth {
//闰年2月只有29号
if IsLeapYear(nYear) && nDay > 29 {
fmt.Println("生日验证失败")
return false
} else if nDay > 28 {
//非闰年2月只有28号
fmt.Println("生日验证失败")
return false
}
} else if 4 == nMonth || 6 == nMonth || 9 == nMonth || 11 == nMonth {
//小月只有30号
if nDay > 30 {
fmt.Println("生日验证失败")
return false
}
}
fmt.Println("生日验证成功&#