You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

137 line
3.1 KiB

  1. package idvalidator
  2. import (
  3. "errors"
  4. "strconv"
  5. "time"
  6. "github.com/guanguans/id-validator/data"
  7. )
  8. // 身份证信息
  9. type idInfo struct {
  10. AddressCode int
  11. Abandoned int
  12. Address string
  13. AddressTree []string
  14. Birthday time.Time
  15. Constellation string
  16. ChineseZodiac string
  17. Sex int
  18. Length int
  19. CheckBit string
  20. }
  21. // 验证身份证号合法性
  22. func IsValid(id string) bool {
  23. code, err := generateCode(id)
  24. if err != nil {
  25. return false
  26. }
  27. // 检查顺序码、生日码、地址码
  28. if !checkOrderCode(code["order"]) || !checkBirthdayCode(code["birthdayCode"]) || !checkAddressCode(code["addressCode"], code["birthdayCode"]) {
  29. return false
  30. }
  31. // 15位身份证不含校验码
  32. if code["type"] == "15" {
  33. return true
  34. }
  35. // 校验码
  36. return code["checkBit"] == generatorCheckBit(code["body"])
  37. }
  38. // 获取身份证信息
  39. func GetInfo(id string) (idInfo, error) {
  40. // 验证有效性
  41. if !IsValid(id) {
  42. return idInfo{}, errors.New("Not Valid ID card number.")
  43. }
  44. code, _ := generateCode(id)
  45. addressCode, _ := strconv.Atoi(code["addressCode"])
  46. // 地址信息
  47. addressInfo := getAddressInfo(code["addressCode"], code["birthdayCode"])
  48. var addressTree []string
  49. for _, val := range addressInfo {
  50. addressTree = append(addressTree, val)
  51. }
  52. // 是否废弃
  53. var abandoned int
  54. if data.AddressCode[addressCode] == "" {
  55. abandoned = 1
  56. }
  57. // 生日
  58. birthday, _ := time.Parse("20060102", code["birthdayCode"])
  59. // 性别
  60. sex := 1
  61. sexCode, _ := strconv.Atoi(code["order"])
  62. if (sexCode % 2) == 0 {
  63. sex = 0
  64. }
  65. // 长度
  66. length, _ := strconv.Atoi(code["type"])
  67. return idInfo{
  68. AddressCode: addressCode,
  69. Abandoned: abandoned,
  70. Address: addressInfo["province"] + addressInfo["city"] + addressInfo["district"],
  71. AddressTree: addressTree,
  72. Birthday: birthday,
  73. Constellation: getConstellation(code["birthdayCode"]),
  74. ChineseZodiac: getChineseZodiac(code["birthdayCode"]),
  75. Sex: sex,
  76. Length: length,
  77. CheckBit: code["checkBit"],
  78. }, nil
  79. }
  80. // 生成假身份证号码
  81. func FakeId() string {
  82. return FakeRequireId(true, "", "", 0)
  83. }
  84. // 按要求生成假身份证号码
  85. // isEighteen 是否生成18位号码
  86. // address 省市县三级地区官方全称:如`北京市`、`台湾省`、`香港特别行政区`、`深圳市`、`黄浦区`
  87. // birthday 出生日期:如 `2000`、`198801`、`19990101`
  88. // sex 性别:1为男性,0为女性
  89. func FakeRequireId(isEighteen bool, address string, birthday string, sex int) string {
  90. // 生成地址码
  91. addressCode := generatorAddressCode(address)
  92. // 出生日期码
  93. birthdayCode := generatorBirthdayCode(birthday)
  94. // 生成顺序码
  95. orderCode := generatorOrderCode(sex)
  96. if !isEighteen {
  97. return addressCode + substr(birthdayCode, 2, 8) + orderCode
  98. }
  99. body := addressCode + birthdayCode + orderCode
  100. return body + generatorCheckBit(body)
  101. }
  102. // 15位升级18位号码
  103. func UpgradeId(id string) (string, error) {
  104. if !IsValid(id) {
  105. return "", errors.New("Not Valid ID card number.")
  106. }
  107. code, _ := generateShortCode(id)
  108. body := code["addressCode"] + code["birthdayCode"] + code["order"]
  109. return body + generatorCheckBit(body), nil
  110. }