idcardvalidate.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package otherutils
  2. import (
  3. "regexp"
  4. "strconv"
  5. "strings"
  6. "time"
  7. )
  8. //城市编号对应关系
  9. /*var code_and_city = [][]string{{"11", "北京"}, {"12", "天津"},
  10. {"13", "河北"}, {"14", "山西"}, {"15", "内蒙古"}, {"21", "辽宁"},
  11. {"22", "吉林"}, {"23", "黑龙江"}, {"31", "上海"}, {"32", "江苏"},
  12. {"33", "浙江"}, {"34", "安徽"}, {"35", "福建"}, {"36", "江西"},
  13. {"37", "山东"}, {"41", "河南"}, {"42", "湖北"}, {"43", "湖南"},
  14. {"44", "广东"}, {"45", "广西"}, {"46", "海南"}, {"50", "重庆"},
  15. {"51", "四川"}, {"52", "贵州"}, {"53", "云南"}, {"54", "西藏"},
  16. {"61", "陕西"}, {"62", "甘肃"}, {"63", "青海"}, {"64", "宁夏"},
  17. {"65", "新疆"}, {"71", "台湾"}, {"81", "香港"}, {"82", "澳门"},
  18. {"91", "国外"}}
  19. */
  20. //城市编号
  21. var code_citys = []string{"11", "12", "13", "14", "15", "21", "22",
  22. "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43",
  23. "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63",
  24. "64", "65", "71", "81", "82", "91"}
  25. //每位加权因子
  26. var powers = []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
  27. //第18位校检码
  28. var verifyCode = []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
  29. // 将15位身份证转换为18位
  30. func convertIdcarBy15Bit(idcard string) string {
  31. if len(idcard) != 15 {
  32. return ""
  33. }
  34. if !isDigital(idcard) {
  35. return ""
  36. }
  37. //130503 670401 001
  38. idcard17 := idcard[:6] + "19" + idcard[6:]
  39. checkCode := checkCode(idcard17)
  40. if len(checkCode) == 0 {
  41. return ""
  42. }
  43. idcard17 += checkCode
  44. return idcard17
  45. }
  46. //将和值与11取模得到余数进行校验码判断
  47. func getCheckCodeBySum(sum17 int) string {
  48. switch sum17 % 11 {
  49. case 10:
  50. return "2"
  51. case 9:
  52. return "3"
  53. case 8:
  54. return "4"
  55. case 7:
  56. return "5"
  57. case 6:
  58. return "6"
  59. case 5:
  60. return "7"
  61. case 4:
  62. return "8"
  63. case 3:
  64. return "9"
  65. case 2:
  66. return "x"
  67. case 1:
  68. return "0"
  69. case 0:
  70. return "1"
  71. }
  72. return ""
  73. }
  74. //判断是否为数字
  75. func isDigital(str string) bool {
  76. var validID = regexp.MustCompile(`^[0-9]*$`)
  77. return validID.MatchString(str)
  78. }
  79. //判断18位身份证的合法性
  80. func isValidate18Idcard(idcard string) bool {
  81. if len(idcard) != 18 {
  82. return false
  83. }
  84. idcard17 := idcard[:17]
  85. idcard18Code := idcard[17:18]
  86. //判断前17位是否都是数字
  87. if !isDigital(idcard17) {
  88. return false
  89. }
  90. //判断前两位是否合法
  91. card_pre_val := false
  92. card_pre := idcard17[:2]
  93. for _, code_city := range code_citys {
  94. if code_city == card_pre {
  95. card_pre_val = true
  96. }
  97. }
  98. if !card_pre_val {
  99. return false
  100. }
  101. //计算加权因子
  102. checkCode := checkCode(idcard17)
  103. if len(checkCode) == 0 {
  104. return false
  105. }
  106. if strings.EqualFold(idcard18Code, checkCode) {
  107. return true
  108. }
  109. return false
  110. }
  111. //计算加权因子
  112. func checkCode(idcard17 string) string {
  113. //将身份证的每位和对应位的加权因子相乘之后,再得到和值
  114. if len(idcard17) != len(powers) {
  115. return ""
  116. }
  117. sum17 := 0
  118. for i := range idcard17 {
  119. char_int, _ := strconv.Atoi(idcard17[i : i+1])
  120. sum17 = sum17 + char_int*powers[i]
  121. }
  122. return getCheckCodeBySum(sum17)
  123. }
  124. //验证所有的身份证的合法性
  125. func ValidatedAllIdCard(idcard string) bool {
  126. if len(idcard) == 15 {
  127. idcard = convertIdcarBy15Bit(idcard)
  128. }
  129. if len(idcard) > 0 {
  130. return isValidate18Idcard(idcard)
  131. }
  132. return false
  133. }
  134. // 是否为防沉迷账号
  135. // cardId 身份证号
  136. // indulgeage 防沉迷年龄 to indulge in; to wallow in; to revel in
  137. func GetAge(cardId string) int {
  138. //, indulgeage int
  139. if !ValidatedAllIdCard(cardId) {
  140. return 0
  141. }
  142. // 判断年龄
  143. birthDay, err := strconv.Atoi(cardId[6:14])
  144. if err != nil {
  145. return 0
  146. }
  147. now_time := time.Now()
  148. ct := now_time.Year()*10000 + int(now_time.Month())*100 + now_time.Day()
  149. return (ct - birthDay) / 10000
  150. }
  151. //验证是否为中文
  152. func CheckZh_cn(str string) bool {
  153. if len(str) < 1 {
  154. return false
  155. }
  156. var hzRegexp = regexp.MustCompile("^[\u4E00-\u9FA5]+$")
  157. return hzRegexp.MatchString(str)
  158. }