gitee.com/gricks/utils@v1.0.8/idcard.go (about)

     1  package utils
     2  
     3  import "time"
     4  
     5  var (
     6  	idCardRatio         = []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
     7  	idCardMap           = []byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
     8  	idCardLength18      = 18
     9  	idCardBirthDayStart = 6
    10  	idCardBirthDayEnd   = 14
    11  )
    12  
    13  func LeapYear(y int) bool {
    14  	return ((y%400 == 0) || (y%4 == 0 && y%100 != 0))
    15  }
    16  
    17  func VerifyIDCard(id string) bool {
    18  	b := []byte(id)
    19  	if len(b) != idCardLength18 {
    20  		return false
    21  	}
    22  	if !verifyIDCardBirthday(b) {
    23  		return false
    24  	}
    25  	if !verifyIDCardCode(b) {
    26  		return false
    27  	}
    28  	return true
    29  }
    30  
    31  // verify first before get age
    32  func GetIDCardAge(id string) int {
    33  	b := []byte(id)
    34  	y, m, d := b2i(b[6:10]), b2i(b[10:12]), b2i(b[12:14])
    35  	t := time.Now()
    36  	ny, nm, nd := t.Date()
    37  	age := ny - y
    38  	if (int(nm) < m) || (int(nm) == m && nd < d) {
    39  		age--
    40  	}
    41  	return age
    42  }
    43  
    44  func verifyIDCardBirthday(id []byte) bool {
    45  	for _, v := range id[6:14] {
    46  		if v > '9' || v < '0' {
    47  			return false
    48  		}
    49  	}
    50  	y, m, d := b2i(id[6:10]), b2i(id[10:12]), b2i(id[12:14])
    51  	switch m {
    52  	case 1, 3, 5, 7, 8, 10, 12:
    53  		if d <= 0 || d > 31 {
    54  			return false
    55  		}
    56  	case 4, 6, 9, 11:
    57  		if d <= 0 || d > 30 {
    58  			return false
    59  		}
    60  	case 2:
    61  		feb := 28
    62  		if LeapYear(y) {
    63  			feb = 29
    64  		}
    65  		if d <= 0 || d > feb {
    66  			return false
    67  		}
    68  	default:
    69  		return false
    70  	}
    71  	return true
    72  }
    73  
    74  func verifyIDCardCode(id []byte) bool {
    75  	return id[idCardLength18-1] == generateIDCardCode(id)
    76  }
    77  
    78  func generateIDCardCode(id []byte) byte {
    79  	code := 0
    80  	for i := 0; i < idCardLength18-1; i++ {
    81  		code += int(id[i]-'0') * idCardRatio[i]
    82  	}
    83  	return idCardMap[code%11]
    84  }
    85  
    86  func b2i(b []byte) int {
    87  	v := 0
    88  	for i := 0; i < len(b); i++ {
    89  		v = v*10 + int(b[i]-'0')
    90  	}
    91  	return v
    92  }