Browse Source

Wip

tags/v1.0.0
guanguans 3 years ago
parent
commit
60b29f571b
3 changed files with 208 additions and 34 deletions
  1. +0
    -32
      Generator.go
  2. +174
    -0
      generator.go
  3. +34
    -2
      id_validator.go

+ 0
- 32
Generator.go View File

@@ -1,32 +0,0 @@
package id_validator

import (
"math"
"strconv"
"strings"
)

func GeneratorCheckBit(body string) string {
// 位置加权
var posWeight [19]float64
for i := 2; i < 19; i++ {
weight := int(math.Pow(2, float64(i-1))) % 11
posWeight[i] = float64(weight)
}

// 累身份证号 body 部分与位置加权的积
bodySum := 0
bodyArray := strings.Split(body, "")
count := len(bodyArray)
for i := 0; i < count; i++ {
bodySubStr, _ := strconv.Atoi(bodyArray[i])
bodySum += bodySubStr * int(posWeight[18-i])
}

// 生成校验码
checkBit := (12 - (bodySum % 11)) % 11
if checkBit == 10 {
return "X"
}
return strconv.Itoa(checkBit)
}

+ 174
- 0
generator.go View File

@@ -0,0 +1,174 @@
package id_validator

import (
"fmt"
"math"
"math/rand"
"regexp"
"strconv"
"strings"
"time"

"id-validator/data"
)

// 生成 Bit 码
func GeneratorCheckBit(body string) string {
// 位置加权
var posWeight [19]float64
for i := 2; i < 19; i++ {
weight := int(math.Pow(2, float64(i-1))) % 11
posWeight[i] = float64(weight)
}

// 累身份证号 body 部分与位置加权的积
bodySum := 0
bodyArray := strings.Split(body, "")
count := len(bodyArray)
for i := 0; i < count; i++ {
bodySubStr, _ := strconv.Atoi(bodyArray[i])
bodySum += bodySubStr * int(posWeight[18-i])
}

// 生成校验码
checkBit := (12 - (bodySum % 11)) % 11
if checkBit == 10 {
return "X"
}
return strconv.Itoa(checkBit)
}

// 生成地址码
func GeneratorAddressCode(address string) string {
var addressCodeInt int
for code, addressStr := range data.AddressCode {
if address == addressStr {
addressCodeInt = code
break
}
}
addressCode := strconv.Itoa(addressCodeInt)

classification := AddressCodeClassification(strconv.Itoa(addressCodeInt))

switch classification {
case "country":
// addressCode = GetRandAddressCode("\\d{4}(?!00)[0-9]{2}$")
addressCode = GetRandAddressCode("\\d{4}(?)[0-9]{2}$")
case "province":
provinceCode := Substr(addressCode, 0, 2)
// pattern := "^" + provinceCode + "\\d{2}(?!00)[0-9]{2}$"
pattern := "^" + provinceCode + "\\d{2}(?)[0-9]{2}$"
addressCode = GetRandAddressCode(pattern)
case "city":
cityCode := Substr(addressCode, 0, 4)
// pattern := "^" + cityCode + "(?!00)[0-9]{2}$"
pattern := "^" + cityCode + "(?)[0-9]{2}$"
addressCode = GetRandAddressCode(pattern)
}

return addressCode
}

// 地址码分类
func AddressCodeClassification(addressCode string) string {
// 全国
if addressCode == "" {
return "country"
}

// 港澳台
if Substr(addressCode, 0, 1) == "8" {
return "special"
}

// 省级
if Substr(addressCode, 2, 6) == "0000" {
return "province"
}

// 市级
if Substr(addressCode, 4, 6) == "00" {
return "city"
}

// 县级
return "district"
}

// 获取随机地址码
func GetRandAddressCode(pattern string) string {
mustCompile := regexp.MustCompile(pattern)

var keys []string
for key, _ := range data.AddressCode {
keyStr := strconv.Itoa(key)
if mustCompile.MatchString(keyStr) && Substr(keyStr, 4, 6) != "00" {
keys = append(keys, keyStr)
}
}

// initialize global pseudo random generator
rand.Seed(time.Now().Unix())
randKey := rand.Intn(len(keys))

return keys[randKey]
}

// 生成出生日期码
func GeneratorBirthdayCode(birthday string) string {
year, _ := strconv.Atoi(DatePad(Substr(birthday, 0, 4), "year"))
month, _ := strconv.Atoi(DatePad(Substr(birthday, 4, 6), "month"))
day, _ := strconv.Atoi(DatePad(Substr(birthday, 6, 8), "day"))

nowYear := time.Now().Year()
rand.Seed(time.Now().Unix())
if year < 1800 || year > nowYear {
randYear := rand.Intn(nowYear-1950) + 1950
year, _ = strconv.Atoi(DatePad(strconv.Itoa(randYear), "year"))
}
if month < 1 || month > 12 {
randMonth := rand.Intn(12-1) + 1
month, _ = strconv.Atoi(DatePad(strconv.Itoa(randMonth), "month"))
}
if day < 1 || day > 31 {
randDay := rand.Intn(28-1) + 1
day, _ = strconv.Atoi(DatePad(strconv.Itoa(randDay), "day"))
}

birthdayStr := strconv.Itoa(year) + strconv.Itoa(month) + strconv.Itoa(day)
_, error := time.Parse("20060102", birthdayStr)
if error != nil {
randYear := rand.Intn(nowYear-1950) + 1950
year, _ = strconv.Atoi(DatePad(strconv.Itoa(randYear), "year"))

randMonth := rand.Intn(12-1) + 1
month, _ = strconv.Atoi(DatePad(strconv.Itoa(randMonth), "month"))

randDay := rand.Intn(28-1) + 1
day, _ = strconv.Atoi(DatePad(strconv.Itoa(randDay), "day"))
}

return strconv.Itoa(year) + strconv.Itoa(month) + strconv.Itoa(day)
}

// 生成顺序码
func GeneratorOrderCode(sex int) string {
rand.Seed(time.Now().Unix())
orderCode := rand.Intn(999-111) + 111
if sex != orderCode%2 {
orderCode -= 1
}

return strconv.Itoa(orderCode)
}

// 日期补全
func DatePad(date string, category string) string {
padLength := 2
if category == "year" {
padLength = 4
}

return fmt.Sprintf("%s%032s", date, "")[:padLength]
}

+ 34
- 2
id_validator.go View File

@@ -1,7 +1,7 @@
package id_validator

import (
"fmt"
"errors"
"strconv"

"id-validator/data"
@@ -39,7 +39,7 @@ func GetInfo(id string) map[string]string {
code := GenerateType(id)

addressInfo := GetAddressInfo(code["addressCode"], code["birthdayCode"])
fmt.Println(addressInfo)
// fmt.Println(addressInfo)
address, _ := strconv.Atoi(code["addressCode"])
abandoned := "0"
if data.AddressCode[address] == "" {
@@ -67,3 +67,35 @@ func GetInfo(id string) map[string]string {

return info
}

// 生成假数据
func FakeId(isEighteen bool, address string, birthday string, sex int) string {
// 生成地址码
addressCode := GeneratorAddressCode(address)

// 出生日期码
birthdayCode := GeneratorBirthdayCode(birthday)

// 顺序码
orderCode := GeneratorOrderCode(sex)

if !isEighteen {
return addressCode + Substr(birthdayCode, 2, 6) + orderCode
}

body := addressCode + birthdayCode + orderCode

return body + GeneratorCheckBit(body)
}

// 15位升级18位号码
func UpgradeId(id string) (string, error) {
if !IsValid(id) {
return "", errors.New("Not Valid ID card number.")
}

code := GenerateShortType(id)
body := code["addressCode"] + code["birthdayCode"] + code["order"]

return body + GeneratorCheckBit(body), nil
}

Loading…
Cancel
Save