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 }