github.com/profzone/eden-framework@v1.0.10/pkg/validate/validatetpl/id_card.go (about)

     1  package validatetpl
     2  
     3  import (
     4  	"regexp"
     5  	"strconv"
     6  	"strings"
     7  )
     8  
     9  const (
    10  	InvalidIDCardNoType  = "身份证号类型错误"
    11  	InvalidIDCardNoValue = "无效的身份证号"
    12  )
    13  
    14  var weights []int64 = []int64{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
    15  
    16  var expectedLastChars = "10X98765432"
    17  
    18  var (
    19  	id_card_regexp = regexp.MustCompile(`^\d{17}(\d|x|X)$`)
    20  )
    21  
    22  func ValidateIDCardNo(v interface{}) (bool, string) {
    23  	s, ok := v.(string)
    24  	if !ok {
    25  		return false, InvalidIDCardNoType
    26  	}
    27  	if !id_card_regexp.MatchString(s) {
    28  		return false, InvalidIDCardNoValue
    29  	}
    30  	if !calculateAndCompareLastChar(s) {
    31  		return false, InvalidIDCardNoValue
    32  	}
    33  	return true, ""
    34  }
    35  
    36  func ValidateIDCardNoOrEmpty(v interface{}) (bool, string) {
    37  	s, ok := v.(string)
    38  	if !ok {
    39  		return false, InvalidIDCardNoType
    40  	}
    41  	if s != "" && !id_card_regexp.MatchString(s) {
    42  		return false, InvalidIDCardNoValue
    43  	}
    44  	if s != "" && !calculateAndCompareLastChar(s) {
    45  		return false, InvalidIDCardNoValue
    46  	}
    47  	return true, ""
    48  }
    49  
    50  func calculateAndCompareLastChar(idCard string) bool {
    51  	var sum int64
    52  	var idCardLength = len(idCard)
    53  	for i := 0; i < idCardLength-1; i++ {
    54  		number, err := strconv.ParseInt(string(idCard[i]), 10, 64)
    55  		if err != nil {
    56  			return false
    57  		}
    58  		sum += number * weights[i]
    59  	}
    60  	n := sum % 11
    61  	expectedLastChar := expectedLastChars[n]
    62  	if string(expectedLastChar) != strings.ToUpper(string(idCard[idCardLength-1])) {
    63  		return false
    64  	}
    65  	return true
    66  }