package IdCardUtil import ( "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 } // Get information from IdCard number. Birthday, gender, province mask. func GetIdCardNoInfo(idCard string) (isValid bool, birthday string, xbm string) { IdCardNo := []byte(idCard) xbm = "1" if !IsValidIdCardNo(&IdCardNo) { isValid = false return } isValid = true // Birthday information. nYear, _ := strconv.Atoi(string(IdCardNo[6:10])) nMonth, _ := strconv.Atoi(string(IdCardNo[10:12])) nDay, _ := strconv.Atoi(string(IdCardNo[12:14])) birthdayUnix := time.Date(nYear, time.Month(nMonth), nDay, 0, 0, 0, 0, time.Local).Unix() //将Unix时间转为时间字符串 timeTemplate := "2006-01-02 15:04:05" birthday = time.Unix(birthdayUnix, 0).Format(timeTemplate) // Gender information. genderMask, _ := strconv.Atoi(string(IdCardNo[16])) if genderMask%2 == 0 { xbm = "2" } else { xbm = "1" } return }