| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- package validator
- import (
- "regexp"
- "strconv"
- "strings"
- "unicode"
- )
- // isValidChineseMobile 验证中国手机号
- func isValidChineseMobile(mobile string) bool {
- // 中国手机号: 1 + (3-9) + 9位数字
- pattern := `^1[3-9]\d{9}$`
- matched, _ := regexp.MatchString(pattern, mobile)
- return matched
- }
- // isValidChineseIDCard 验证中国身份证号
- func isValidChineseIDCard(idCard string) bool {
- // 支持15位和18位
- if len(idCard) != 15 && len(idCard) != 18 {
- return false
- }
- if len(idCard) == 18 {
- return isValid18IDCard(idCard)
- }
- // 15位身份证验证(旧版)
- pattern := `^\d{15}$`
- matched, _ := regexp.MatchString(pattern, idCard)
- return matched
- }
- // isValid18IDCard 验证18位身份证
- func isValid18IDCard(idCard string) bool {
- // 基本格式验证: 6位地区码 + 8位出生日期 + 3位顺序码 + 1位校验码
- pattern := `^\d{17}[\dXx]$`
- matched, _ := regexp.MatchString(pattern, idCard)
- if !matched {
- return false
- }
- // 校验位验证(简化版)
- // 权重因子
- weights := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
- // 校验码
- checkCodes := []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
- sum := 0
- for i := 0; i < 17; i++ {
- digit, _ := strconv.Atoi(string(idCard[i]))
- sum += digit * weights[i]
- }
- checkCode := checkCodes[sum%11]
- lastChar := strings.ToUpper(string(idCard[17]))
- return checkCode == lastChar
- }
- // isValidChineseName 验证中文姓名
- func isValidChineseName(name string) bool {
- if name == "" {
- return false
- }
- // 长度检查: 2-20个字符
- runeCount := len([]rune(name))
- if runeCount < 2 || runeCount > 20 {
- return false
- }
- // 检查是否包含中文字符
- hasChinese := false
- for _, r := range name {
- if unicode.Is(unicode.Han, r) {
- hasChinese = true
- }
- }
- if !hasChinese {
- return false
- }
- // 允许中文、·(间隔号,用于少数民族姓名)
- pattern := `^[\p{Han}·]+$`
- matched, _ := regexp.MatchString(pattern, name)
- return matched
- }
- // isValidChinesePostcode 验证中国邮政编码
- func isValidChinesePostcode(postcode string) bool {
- // 中国邮政编码: 6位数字
- pattern := `^\d{6}$`
- matched, _ := regexp.MatchString(pattern, postcode)
- return matched
- }
- // isValidUSCC 验证统一社会信用代码
- func isValidUSCC(uscc string) bool {
- // 统一社会信用代码: 18位
- if len(uscc) != 18 {
- return false
- }
- // 基本格式验证
- pattern := `^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$`
- matched, _ := regexp.MatchString(pattern, uscc)
- if !matched {
- return false
- }
- // TODO: 添加校验位算法验证
- return true
- }
- // isValidBankCard 验证银行卡号(Luhn 算法)
- func isValidBankCard(cardNumber string) bool {
- // 移除空格
- cardNumber = strings.ReplaceAll(cardNumber, " ", "")
- // 长度检查: 13-19位
- if len(cardNumber) < 13 || len(cardNumber) > 19 {
- return false
- }
- // 必须全是数字
- for _, r := range cardNumber {
- if !unicode.IsDigit(r) {
- return false
- }
- }
- // Luhn 算法验证
- return luhnCheck(cardNumber)
- }
- // luhnCheck Luhn 算法校验
- func luhnCheck(cardNumber string) bool {
- sum := 0
- alternate := false
- // 从右往左遍历
- for i := len(cardNumber) - 1; i >= 0; i-- {
- digit, _ := strconv.Atoi(string(cardNumber[i]))
- if alternate {
- digit *= 2
- if digit > 9 {
- digit -= 9
- }
- }
- sum += digit
- alternate = !alternate
- }
- return sum%10 == 0
- }
|