|
- package id_validator
-
- import (
- "id-validator/data"
- "math"
- "math/rand"
- "regexp"
- "strconv"
- "strings"
- "time"
- )
-
- // 生成 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 := DatePad(strconv.Itoa(year), "year") + DatePad(strconv.Itoa(month), "month") + DatePad(strconv.Itoa(day), "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 DatePad(strconv.Itoa(year), "year") + DatePad(strconv.Itoa(month), "month") + DatePad(strconv.Itoa(day), "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
- }
-
- for i := 0; i < padLength; i++ {
- length := len([]rune(date))
- if length < padLength {
- // date = fmt.Sprintf("%s%s", "0", date)
- date = "0" + date
- }
- }
-
- return date
- }
|