From 60b29f571b9e818fbecaa43633d2ced929560c0c Mon Sep 17 00:00:00 2001 From: guanguans Date: Sun, 10 Jan 2021 19:22:33 +0800 Subject: [PATCH] Wip --- Generator.go | 32 --------- generator.go | 174 ++++++++++++++++++++++++++++++++++++++++++++++++ id_validator.go | 36 +++++++++- 3 files changed, 208 insertions(+), 34 deletions(-) delete mode 100644 Generator.go create mode 100644 generator.go diff --git a/Generator.go b/Generator.go deleted file mode 100644 index 257c0bb..0000000 --- a/Generator.go +++ /dev/null @@ -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) -} diff --git a/generator.go b/generator.go new file mode 100644 index 0000000..6e89a35 --- /dev/null +++ b/generator.go @@ -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] +} diff --git a/id_validator.go b/id_validator.go index bc5576d..423b652 100644 --- a/id_validator.go +++ b/id_validator.go @@ -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 +}