github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/chinaid/api.go (about) 1 package chinaid 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "math/rand" 8 "strconv" 9 "time" 10 ) 11 12 // ProvinceAndCity 返回随机省/城市 13 func ProvinceAndCity() string { 14 return ProvinceCity[RandInt(0, len(ProvinceCity))] 15 } 16 17 // Address 返回随机地址 18 func Address() string { 19 return ProvinceAndCity() + 20 RandChinese(2, 3) + "路" + 21 strconv.Itoa(RandInt(1, 8000)) + "号" + 22 RandChinese(2, 3) + "小区" + 23 strconv.Itoa(RandInt(1, 20)) + "单元" + 24 strconv.Itoa(RandInt(101, 2500)) + "室" 25 } 26 27 // BankNo 返回随机银行卡号,银行卡号符合LUHN 算法并且有正确的卡 bin 前缀 28 func BankNo() string { 29 // 随机选中银行卡卡头 30 bank := CardBins[RandInt(0, len(CardBins))] 31 // 获取 卡前缀(cardBin) 32 prefixes := bank.Prefixes 33 // 获取当前银行卡正确长度 34 cardNoLength := bank.Length 35 // 生成 长度-1 位卡号 36 preCardNo := strconv.Itoa(prefixes[RandInt(0, len(prefixes))]) + 37 fmt.Sprintf("%0*d", cardNoLength-7, RandInt64(0, int64(math.Pow10(cardNoLength-7)))) 38 // LUHN 算法处理 39 return LUHNProcess(preCardNo) 40 } 41 42 // LUHNProcess 通过 LUHN 合成卡号处理给定的银行卡号 43 func LUHNProcess(preCardNo string) string { 44 checkSum := 0 45 tmpCardNo := reverseString(preCardNo) 46 for i, s := range tmpCardNo { 47 // 数据层确保卡号正确 48 tmp, _ := strconv.Atoi(string(s)) 49 // 由于卡号实际少了一位,所以反转后卡号第一位一定为偶数位 50 // 同时 i 正好也是偶数,此时 i 将和卡号奇偶位同步 51 if i%2 == 0 { 52 // 偶数位 *2 是否为两位数(>9) 53 if tmp*2 > 9 { 54 // 如果为两位数则 -9 55 checkSum += tmp*2 - 9 56 } else { 57 // 否则直接相加即可 58 checkSum += tmp * 2 59 } 60 } else { 61 // 奇数位直接相加 62 checkSum += tmp 63 } 64 } 65 if checkSum%10 != 0 { 66 return preCardNo + strconv.Itoa(10-checkSum%10) 67 } else { 68 // 如果不巧生成的前 卡长度-1 位正好符合 LUHN 算法 69 // 那么需要递归重新生成(需要符合 cardBind 中卡号长度) 70 return BankNo() 71 } 72 } 73 74 // Email 返回随机邮箱,邮箱目前只支持常见的域名后缀 75 func Email() string { 76 return RandSmallLetters(8) + "@" + RandSmallLetters(5) + DomainSuffix[RandInt(0, len(DomainSuffix))] 77 } 78 79 // IssueOrg 返回身份证签发机关(eg: XXX公安局/XX区分局) 80 func IssueOrg() string { 81 return CityName[RandInt(0, len(CityName))] + "公安局某某分局" 82 } 83 84 // ValidPeriod 返回身份证有效期限(eg: 20150906-20350906),有效期限固定为 20 年 85 func ValidPeriod() string { 86 begin := RandDate() 87 end := begin.AddDate(20, 0, 0) 88 return begin.Format("20060102") + "-" + end.Format("20060102") 89 } 90 91 // ChinaID 返回中国大陆地区身份证号. 92 func ChinaID() string { 93 // AreaCode 随机一个+4位随机数字(不够左填充0) 94 areaCode := AreaCode[RandInt(0, len(AreaCode))] + 95 fmt.Sprintf("%0*d", 4, RandInt(1, 9999)) 96 birthday := RandDate().Format("20060102") 97 randomCode := fmt.Sprintf("%0*d", 3, RandInt(0, 999)) 98 prefix := areaCode + birthday + randomCode 99 return prefix + verifyCode(prefix) 100 } 101 102 // verifyCode 通过给定的身份证号生成最后一位的 verifyCode 103 func verifyCode(cardId string) string { 104 tmp := 0 105 for i, v := range Wi { 106 t, _ := strconv.Atoi(string(cardId[i])) 107 tmp += t * v 108 } 109 return ValCodeArr[tmp%11] 110 } 111 112 // RandDate 返回随机时间,时间区间从 1970 年 ~ 2020 年 113 func RandDate() time.Time { 114 begin, _ := time.Parse("2006-01-02 15:04:05", "1970-01-01 00:00:00") 115 end, _ := time.Parse("2006-01-02 15:04:05", "2020-01-01 00:00:00") 116 return RandDateRange(begin, end) 117 } 118 119 // RandDateRange 返回随机时间,时间区间从 1970 年 ~ 2020 年 120 func RandDateRange(from, to time.Time) time.Time { 121 return time.Unix(RandInt64(from.Unix(), to.Unix()), 0) 122 } 123 124 // Mobile 返回中国大陆地区手机号 125 func Mobile() string { 126 return MobilePrefix[RandInt(0, len(MobilePrefix))] + fmt.Sprintf("%0*d", 8, RandInt(0, 100000000)) 127 } 128 129 // Sex 返回性别 130 func Sex() string { 131 if RandInt(0, 2) == 0 { 132 return "男" 133 } 134 return "女" 135 } 136 137 // Name 返回中国姓名,姓名已经尽量返回常用姓氏和名字 138 func Name() string { 139 return Surnames[RandInt(0, len(Surnames))] + RandChineseN(2) 140 } 141 142 // RandChineseN 指定长度随机中文字符(包含复杂字符)。 143 func RandChineseN(n int) string { 144 var buf bytes.Buffer 145 for i := 0; i < n; i++ { 146 buf.WriteRune(rune(RandInt(19968, 40869))) 147 } 148 return buf.String() 149 } 150 151 // RandChinese 指定范围随机中文字符. 152 func RandChinese(minLen, maxLen int) string { 153 return RandChineseN(RandInt(minLen, maxLen)) 154 } 155 156 // RandSmallLetters 随机英文小写字母. 157 func RandSmallLetters(len int) string { 158 data := make([]byte, len) 159 for i := 0; i < len; i++ { 160 data[i] = byte(rand.Intn(26) + 97) 161 } 162 return string(data) 163 } 164 165 // RandInt 指定范围随机 int 166 func RandInt(min, max int) int { 167 if min >= max { 168 return min 169 } 170 171 return min + rand.Intn(max-min) 172 } 173 174 // RandInt64 指定范围随机 int64 175 func RandInt64(min, max int64) int64 { 176 return min + rand.Int63n(max-min) 177 } 178 179 // 反转字符串 180 func reverseString(s string) string { 181 runes := []rune(s) 182 for from, to := 0, len(runes)-1; from < to; from, to = from+1, to-1 { 183 runes[from], runes[to] = runes[to], runes[from] 184 } 185 return string(runes) 186 }