github.com/gogf/gf@v1.16.9/util/gvalid/gvalid_validator_rule_resident_id.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gvalid
     8  
     9  import (
    10  	"github.com/gogf/gf/text/gregex"
    11  	"strconv"
    12  	"strings"
    13  )
    14  
    15  // checkResidentId checks whether given id a china resident id number.
    16  //
    17  // xxxxxx yyyy MM dd 375 0  十八位
    18  // xxxxxx   yy MM dd  75 0  十五位
    19  //
    20  // 地区:     [1-9]\d{5}
    21  // 年的前两位:(18|19|([23]\d))  1800-2399
    22  // 年的后两位:\d{2}
    23  // 月份:     ((0[1-9])|(10|11|12))
    24  // 天数:     (([0-2][1-9])|10|20|30|31) 闰年不能禁止29+
    25  //
    26  // 三位顺序码:\d{3}
    27  // 两位顺序码:\d{2}
    28  // 校验码:   [0-9Xx]
    29  //
    30  // 十八位:^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$
    31  // 十五位:^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$
    32  //
    33  // 总:
    34  // (^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)
    35  func (v *Validator) checkResidentId(id string) bool {
    36  	id = strings.ToUpper(strings.TrimSpace(id))
    37  	if len(id) != 18 {
    38  		return false
    39  	}
    40  	var (
    41  		weightFactor = []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
    42  		checkCode    = []byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
    43  		last         = id[17]
    44  		num          = 0
    45  	)
    46  	for i := 0; i < 17; i++ {
    47  		tmp, err := strconv.Atoi(string(id[i]))
    48  		if err != nil {
    49  			return false
    50  		}
    51  		num = num + tmp*weightFactor[i]
    52  	}
    53  	if checkCode[num%11] != last {
    54  		return false
    55  	}
    56  
    57  	return gregex.IsMatchString(`(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)`, id)
    58  }