|
|
|
@ -1,191 +1,19 @@
|
|
|
|
|
package IdCardUtil
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/bluesky335/IDCheck/IdNumber"
|
|
|
|
|
"strconv"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var weight = [17]int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
|
|
|
|
|
var validValue = [11]byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
|
|
|
|
|
var validProvince = []string{
|
|
|
|
|
"11", // 北京市
|
|
|
|
|
"12", // 天津市
|
|
|
|
|
"13", // 河北省
|
|
|
|
|
"14", // 山西省
|
|
|
|
|
"15", // 内蒙古自治区
|
|
|
|
|
"21", // 辽宁省
|
|
|
|
|
"22", // 吉林省
|
|
|
|
|
"23", // 黑龙江省
|
|
|
|
|
"31", // 上海市
|
|
|
|
|
"32", // 江苏省
|
|
|
|
|
"33", // 浙江省
|
|
|
|
|
"34", // 安徽省
|
|
|
|
|
"35", // 福建省
|
|
|
|
|
"36", // 山西省
|
|
|
|
|
"37", // 山东省
|
|
|
|
|
"41", // 河南省
|
|
|
|
|
"42", // 湖北省
|
|
|
|
|
"43", // 湖南省
|
|
|
|
|
"44", // 广东省
|
|
|
|
|
"45", // 广西壮族自治区
|
|
|
|
|
"46", // 海南省
|
|
|
|
|
"50", // 重庆市
|
|
|
|
|
"51", // 四川省
|
|
|
|
|
"52", // 贵州省
|
|
|
|
|
"53", // 云南省
|
|
|
|
|
"54", // 西藏自治区
|
|
|
|
|
"61", // 陕西省
|
|
|
|
|
"62", // 甘肃省
|
|
|
|
|
"63", // 青海省
|
|
|
|
|
"64", // 宁夏回族自治区
|
|
|
|
|
"65", // 新疆维吾尔自治区
|
|
|
|
|
"71", // 台湾省
|
|
|
|
|
"81", // 香港特别行政区
|
|
|
|
|
"82", // 澳门特别行政区
|
|
|
|
|
"91", // 海外
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check IdCard number 18 valid.
|
|
|
|
|
func IsValidIdCardNo18(IdCardNo18 *[]byte) bool {
|
|
|
|
|
nLen := len(*IdCardNo18)
|
|
|
|
|
if nLen != 18 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nSum := 0
|
|
|
|
|
for i := 0; i < nLen-1; i++ {
|
|
|
|
|
n, _ := strconv.Atoi(string((*IdCardNo18)[i]))
|
|
|
|
|
nSum += n * weight[i]
|
|
|
|
|
}
|
|
|
|
|
mod := nSum % 11
|
|
|
|
|
if validValue[mod] == (*IdCardNo18)[17] {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert IdCard 15 to 18.
|
|
|
|
|
func IdCard15To18(IdCardNo15 []byte) []byte {
|
|
|
|
|
nLen := len(IdCardNo15)
|
|
|
|
|
if nLen != 15 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IdCardNo18 := make([]byte, 0)
|
|
|
|
|
IdCardNo18 = append(IdCardNo18, IdCardNo15[:6]...)
|
|
|
|
|
IdCardNo18 = append(IdCardNo18, '1', '9')
|
|
|
|
|
IdCardNo18 = append(IdCardNo18, IdCardNo15[6:]...)
|
|
|
|
|
|
|
|
|
|
sum := 0
|
|
|
|
|
for i, v := range IdCardNo18 {
|
|
|
|
|
n, _ := strconv.Atoi(string(v))
|
|
|
|
|
sum += n * weight[i]
|
|
|
|
|
}
|
|
|
|
|
mod := sum % 11
|
|
|
|
|
IdCardNo18 = append(IdCardNo18, validValue[mod])
|
|
|
|
|
|
|
|
|
|
return IdCardNo18
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func IsLeapYear(nYear int) bool {
|
|
|
|
|
if nYear <= 0 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nYear%4 == 0 && nYear%100 != 0) || nYear%400 == 0 {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check birthday's year month day valid.
|
|
|
|
|
func CheckBirthdayValid(nYear, nMonth, nDay int) bool {
|
|
|
|
|
if nYear < 1900 || nMonth <= 0 || nMonth > 12 || nDay <= 0 || nDay > 31 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curYear, curMonth, curDay := time.Now().Date()
|
|
|
|
|
if nYear == curYear {
|
|
|
|
|
if nMonth > int(curMonth) {
|
|
|
|
|
return false
|
|
|
|
|
} else if nMonth == int(curMonth) && nDay > curDay {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if 2 == nMonth {
|
|
|
|
|
if IsLeapYear(nYear) && nDay > 29 {
|
|
|
|
|
return false
|
|
|
|
|
} else if nDay > 28 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
} else if 4 == nMonth || 6 == nMonth || 9 == nMonth || 11 == nMonth {
|
|
|
|
|
if nDay > 30 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check province code valid.
|
|
|
|
|
func CheckProvinceValid(IdCardNo []byte) bool {
|
|
|
|
|
provinceCode := make([]byte, 0)
|
|
|
|
|
provinceCode = append(provinceCode, IdCardNo[:2]...)
|
|
|
|
|
provinceStr := string(provinceCode)
|
|
|
|
|
|
|
|
|
|
for i, _ := range validProvince {
|
|
|
|
|
if provinceStr == validProvince[i] {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check IdCard number valid.
|
|
|
|
|
func IsValidIdCardNo(IdCardNo *[]byte) bool {
|
|
|
|
|
nLen := len(*IdCardNo)
|
|
|
|
|
if nLen != 15 && nLen != 18 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, v := range *IdCardNo {
|
|
|
|
|
n, _ := strconv.Atoi(string(v))
|
|
|
|
|
if n >= 0 && n <= 9 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v == 'X' && i == 16 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !CheckProvinceValid(*IdCardNo) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if nLen == 15 {
|
|
|
|
|
*IdCardNo = IdCard15To18(*IdCardNo)
|
|
|
|
|
if IdCardNo == nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
} else if !IsValidIdCardNo18(IdCardNo) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nYear, _ := strconv.Atoi(string((*IdCardNo)[6:10]))
|
|
|
|
|
nMonth, _ := strconv.Atoi(string((*IdCardNo)[10:12]))
|
|
|
|
|
nDay, _ := strconv.Atoi(string((*IdCardNo)[12:14]))
|
|
|
|
|
if !CheckBirthdayValid(nYear, nMonth, nDay) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
var id = IdNumber.New(string(*IdCardNo))
|
|
|
|
|
return id.IsValid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get information from IdCard number. Birthday, gender, province mask.
|
|
|
|
|