Compare commits
	
		
			No commits in common. "main" and "v1.0.0" have entirely different histories.
		
	
	
		
	
		
@ -5,8 +5,3 @@ All notable changes to `guanguans/id-validator` will be documented in this file
 | 
			
		||||
## 1.0.0 - 2021-01-21
 | 
			
		||||
 | 
			
		||||
* Initial release.
 | 
			
		||||
 | 
			
		||||
## 1.0.1 - 2021-01-27
 | 
			
		||||
 | 
			
		||||
* Change the access control of some functions.
 | 
			
		||||
* Add bench testing.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Makefile
									
									
									
									
									
								
							@ -1,6 +1,5 @@
 | 
			
		||||
# note: call scripts from /scripts
 | 
			
		||||
GOCMD=GO111MODULE=on go
 | 
			
		||||
LOCALCMD=/usr/local
 | 
			
		||||
 | 
			
		||||
linters-install:
 | 
			
		||||
	@golangci-lint --version >/dev/null 2>&1 || { \
 | 
			
		||||
@ -9,16 +8,12 @@ linters-install:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
lint: linters-install
 | 
			
		||||
	 $(LOCALCMD)/bin/golangci-lint run
 | 
			
		||||
 | 
			
		||||
fmt:
 | 
			
		||||
	$(GOCMD) fmt ./...
 | 
			
		||||
 | 
			
		||||
vet:
 | 
			
		||||
	$(GOCMD) vet ./.
 | 
			
		||||
	$(PWD)/bin/golangci-lint run
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	$(GOCMD) test -cover -race ./...
 | 
			
		||||
 | 
			
		||||
bench:
 | 
			
		||||
	$(GOCMD) test -bench=. -benchmem ./...
 | 
			
		||||
 | 
			
		||||
.PHONY: test lint linters-install
 | 
			
		||||
 | 
			
		||||
@ -81,7 +81,7 @@ func main() {
 | 
			
		||||
## Testing
 | 
			
		||||
 | 
			
		||||
``` bash
 | 
			
		||||
$ make test
 | 
			
		||||
$ go test
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Changelog
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ func main() {
 | 
			
		||||
## 测试
 | 
			
		||||
 | 
			
		||||
``` bash
 | 
			
		||||
$ make test
 | 
			
		||||
$ go test
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 变更日志
 | 
			
		||||
 | 
			
		||||
@ -1,88 +0,0 @@
 | 
			
		||||
package idvalidator
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func BenchmarkIsValid(b *testing.B) {
 | 
			
		||||
	benchmarks := []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		id   string
 | 
			
		||||
	}{
 | 
			
		||||
		{id: "440308199901101512"},
 | 
			
		||||
		{id: "610104620927690"},
 | 
			
		||||
		{id: "810000199408230021"},
 | 
			
		||||
		{id: "830000199201300022"},
 | 
			
		||||
	}
 | 
			
		||||
	for _, bm := range benchmarks {
 | 
			
		||||
		b.Run(bm.name, func(b *testing.B) {
 | 
			
		||||
			for i := 0; i < b.N; i++ {
 | 
			
		||||
				IsValid(bm.name)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkGetInfo(b *testing.B) {
 | 
			
		||||
	benchmarks := []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		id   string
 | 
			
		||||
	}{
 | 
			
		||||
		{id: "440308199901101512"},
 | 
			
		||||
		{id: "610104620927690"},
 | 
			
		||||
		{id: "810000199408230021"},
 | 
			
		||||
		{id: "830000199201300022"},
 | 
			
		||||
	}
 | 
			
		||||
	for _, bm := range benchmarks {
 | 
			
		||||
		b.Run(bm.name, func(b *testing.B) {
 | 
			
		||||
			for i := 0; i < b.N; i++ {
 | 
			
		||||
				GetInfo(bm.name)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkFakeId(b *testing.B) {
 | 
			
		||||
	for i := 0; i < b.N; i++ {
 | 
			
		||||
		FakeId()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkFakeRequireId(b *testing.B) {
 | 
			
		||||
	benchmarks := []struct {
 | 
			
		||||
		name       string
 | 
			
		||||
		isEighteen bool
 | 
			
		||||
		address    string
 | 
			
		||||
		birthday   string
 | 
			
		||||
		sex        int
 | 
			
		||||
	}{
 | 
			
		||||
		{isEighteen: false, address: "浙江省", birthday: "20000101", sex: 1},
 | 
			
		||||
		{isEighteen: true, address: "浙江省", birthday: "20000101", sex: 0},
 | 
			
		||||
		{isEighteen: true, address: "台湾省", birthday: "20000101", sex: 0},
 | 
			
		||||
		{isEighteen: true, address: "香港特别行政区", birthday: "20000101", sex: 0},
 | 
			
		||||
	}
 | 
			
		||||
	for _, bm := range benchmarks {
 | 
			
		||||
		b.Run(bm.name, func(b *testing.B) {
 | 
			
		||||
			for i := 0; i < b.N; i++ {
 | 
			
		||||
				FakeRequireId(bm.isEighteen, bm.address, bm.birthday, bm.sex)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkUpgradeId(b *testing.B) {
 | 
			
		||||
	benchmarks := []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		id   string
 | 
			
		||||
	}{
 | 
			
		||||
		{id: "610104620927690"},
 | 
			
		||||
		{id: "61010462092769"},
 | 
			
		||||
	}
 | 
			
		||||
	for _, bm := range benchmarks {
 | 
			
		||||
		b.Run(bm.name, func(b *testing.B) {
 | 
			
		||||
			for i := 0; i < b.N; i++ {
 | 
			
		||||
				UpgradeId(bm.id)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								checker.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								checker.go
									
									
									
									
									
								
							@ -9,28 +9,28 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 检查ID参数
 | 
			
		||||
func checkIdArgument(id string) bool {
 | 
			
		||||
	_, err := generateCode(id)
 | 
			
		||||
func CheckIdArgument(id string) bool {
 | 
			
		||||
	_, err := GenerateCode(id)
 | 
			
		||||
 | 
			
		||||
	return err == nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生成数据
 | 
			
		||||
func generateCode(id string) (map[string]string, error) {
 | 
			
		||||
func GenerateCode(id string) (map[string]string, error) {
 | 
			
		||||
	length := len(id)
 | 
			
		||||
	if length == 15 {
 | 
			
		||||
		return generateShortCode(id)
 | 
			
		||||
		return GenerateShortCode(id)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if length == 18 {
 | 
			
		||||
		return generateLongCode(id)
 | 
			
		||||
		return GenerateLongCode(id)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return map[string]string{}, errors.New("Invalid ID card number length.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生成短数据
 | 
			
		||||
func generateShortCode(id string) (map[string]string, error) {
 | 
			
		||||
func GenerateShortCode(id string) (map[string]string, error) {
 | 
			
		||||
	if len(id) != 15 {
 | 
			
		||||
		return map[string]string{}, errors.New("Invalid ID card number length.")
 | 
			
		||||
	}
 | 
			
		||||
@ -49,7 +49,7 @@ func generateShortCode(id string) (map[string]string, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生成长数据
 | 
			
		||||
func generateLongCode(id string) (map[string]string, error) {
 | 
			
		||||
func GenerateLongCode(id string) (map[string]string, error) {
 | 
			
		||||
	if len(id) != 18 {
 | 
			
		||||
		return map[string]string{}, errors.New("Invalid ID card number length.")
 | 
			
		||||
	}
 | 
			
		||||
@ -67,13 +67,13 @@ func generateLongCode(id string) (map[string]string, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 检查地址码
 | 
			
		||||
func checkAddressCode(addressCode string, birthdayCode string) bool {
 | 
			
		||||
	return getAddressInfo(addressCode, birthdayCode)["province"] != ""
 | 
			
		||||
func CheckAddressCode(addressCode string, birthdayCode string) bool {
 | 
			
		||||
	return GetAddressInfo(addressCode, birthdayCode)["province"] != ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 检查出生日期码
 | 
			
		||||
func checkBirthdayCode(birthdayCode string) bool {
 | 
			
		||||
	year, _ := strconv.Atoi(substr(birthdayCode, 0, 4))
 | 
			
		||||
func CheckBirthdayCode(birthdayCode string) bool {
 | 
			
		||||
	year, _ := strconv.Atoi(Substr(birthdayCode, 0, 4))
 | 
			
		||||
	if year < 1800 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
@ -89,6 +89,6 @@ func checkBirthdayCode(birthdayCode string) bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 检查顺序码
 | 
			
		||||
func checkOrderCode(orderCode string) bool {
 | 
			
		||||
func CheckOrderCode(orderCode string) bool {
 | 
			
		||||
	return len(orderCode) == 3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										50
									
								
								generator.go
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								generator.go
									
									
									
									
									
								
							@ -11,7 +11,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 生成Bit码
 | 
			
		||||
func generatorCheckBit(body string) string {
 | 
			
		||||
func GeneratorCheckBit(body string) string {
 | 
			
		||||
	// 位置加权
 | 
			
		||||
	var posWeight [19]float64
 | 
			
		||||
	for i := 2; i < 19; i++ {
 | 
			
		||||
@ -37,7 +37,7 @@ func generatorCheckBit(body string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生成地址码
 | 
			
		||||
func generatorAddressCode(address string) string {
 | 
			
		||||
func GeneratorAddressCode(address string) string {
 | 
			
		||||
	addressCode := ""
 | 
			
		||||
	for code, addressStr := range data.AddressCode {
 | 
			
		||||
		if address == addressStr {
 | 
			
		||||
@ -46,45 +46,45 @@ func generatorAddressCode(address string) string {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	classification := addressCodeClassification(addressCode)
 | 
			
		||||
	classification := AddressCodeClassification(addressCode)
 | 
			
		||||
	switch classification {
 | 
			
		||||
	case "country":
 | 
			
		||||
		// addressCode = getRandAddressCode("\\d{4}(?!00)[0-9]{2}$")
 | 
			
		||||
		addressCode = getRandAddressCode("\\d{4}(?)[0-9]{2}$")
 | 
			
		||||
		// addressCode = GetRandAddressCode("\\d{4}(?!00)[0-9]{2}$")
 | 
			
		||||
		addressCode = GetRandAddressCode("\\d{4}(?)[0-9]{2}$")
 | 
			
		||||
	case "province":
 | 
			
		||||
		provinceCode := substr(addressCode, 0, 2)
 | 
			
		||||
		provinceCode := Substr(addressCode, 0, 2)
 | 
			
		||||
		// pattern := "^" + provinceCode + "\\d{2}(?!00)[0-9]{2}$"
 | 
			
		||||
		pattern := "^" + provinceCode + "\\d{2}(?)[0-9]{2}$"
 | 
			
		||||
		addressCode = getRandAddressCode(pattern)
 | 
			
		||||
		addressCode = GetRandAddressCode(pattern)
 | 
			
		||||
	case "city":
 | 
			
		||||
		cityCode := substr(addressCode, 0, 4)
 | 
			
		||||
		cityCode := Substr(addressCode, 0, 4)
 | 
			
		||||
		// pattern := "^" + cityCode + "(?!00)[0-9]{2}$"
 | 
			
		||||
		pattern := "^" + cityCode + "(?)[0-9]{2}$"
 | 
			
		||||
		addressCode = getRandAddressCode(pattern)
 | 
			
		||||
		addressCode = GetRandAddressCode(pattern)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return addressCode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 地址码分类
 | 
			
		||||
func addressCodeClassification(addressCode string) string {
 | 
			
		||||
func AddressCodeClassification(addressCode string) string {
 | 
			
		||||
	// 全国
 | 
			
		||||
	if addressCode == "" {
 | 
			
		||||
		return "country"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 港澳台
 | 
			
		||||
	if substr(addressCode, 0, 1) == "8" {
 | 
			
		||||
	if Substr(addressCode, 0, 1) == "8" {
 | 
			
		||||
		return "special"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 省级
 | 
			
		||||
	if substr(addressCode, 2, 6) == "0000" {
 | 
			
		||||
	if Substr(addressCode, 2, 6) == "0000" {
 | 
			
		||||
		return "province"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 市级
 | 
			
		||||
	if substr(addressCode, 4, 6) == "00" {
 | 
			
		||||
	if Substr(addressCode, 4, 6) == "00" {
 | 
			
		||||
		return "city"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -93,12 +93,12 @@ func addressCodeClassification(addressCode string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取随机地址码
 | 
			
		||||
func getRandAddressCode(pattern string) string {
 | 
			
		||||
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" {
 | 
			
		||||
		if mustCompile.MatchString(keyStr) && Substr(keyStr, 4, 6) != "00" {
 | 
			
		||||
			keys = append(keys, keyStr)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -109,25 +109,25 @@ func getRandAddressCode(pattern string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生成出生日期码
 | 
			
		||||
func generatorBirthdayCode(birthday string) string {
 | 
			
		||||
	year := datePipelineHandle(datePad(substr(birthday, 0, 4), "year"), "year")
 | 
			
		||||
	month := datePipelineHandle(datePad(substr(birthday, 4, 6), "month"), "month")
 | 
			
		||||
	day := datePipelineHandle(datePad(substr(birthday, 6, 8), "day"), "day")
 | 
			
		||||
func GeneratorBirthdayCode(birthday string) string {
 | 
			
		||||
	year := DatePipelineHandle(DatePad(Substr(birthday, 0, 4), "year"), "year")
 | 
			
		||||
	month := DatePipelineHandle(DatePad(Substr(birthday, 4, 6), "month"), "month")
 | 
			
		||||
	day := DatePipelineHandle(DatePad(Substr(birthday, 6, 8), "day"), "day")
 | 
			
		||||
 | 
			
		||||
	birthday = year + month + day
 | 
			
		||||
	_, error := time.Parse("20060102", birthday)
 | 
			
		||||
	// example: 195578
 | 
			
		||||
	if error != nil {
 | 
			
		||||
		year = datePad(year, "year")
 | 
			
		||||
		month = datePad(month, "month")
 | 
			
		||||
		day = datePad(day, "day")
 | 
			
		||||
		year = DatePad(year, "year")
 | 
			
		||||
		month = DatePad(month, "month")
 | 
			
		||||
		day = DatePad(day, "day")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return year + month + day
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 日期处理
 | 
			
		||||
func datePipelineHandle(date string, category string) string {
 | 
			
		||||
func DatePipelineHandle(date string, category string) string {
 | 
			
		||||
	dateInt, _ := strconv.Atoi(date)
 | 
			
		||||
 | 
			
		||||
	switch category {
 | 
			
		||||
@ -155,7 +155,7 @@ func datePipelineHandle(date string, category string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生成顺序码
 | 
			
		||||
func generatorOrderCode(sex int) string {
 | 
			
		||||
func GeneratorOrderCode(sex int) string {
 | 
			
		||||
	rand.Seed(time.Now().Unix())
 | 
			
		||||
	orderCode := rand.Intn(999-111) + 111
 | 
			
		||||
	if sex != orderCode%2 {
 | 
			
		||||
@ -166,7 +166,7 @@ func generatorOrderCode(sex int) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 日期补全
 | 
			
		||||
func datePad(date string, category string) string {
 | 
			
		||||
func DatePad(date string, category string) string {
 | 
			
		||||
	padLength := 2
 | 
			
		||||
	if category == "year" {
 | 
			
		||||
		padLength = 4
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
			
		||||
module golib.gaore.com/GaoreGo/id-validator
 | 
			
		||||
module github.com/guanguans/id-validator
 | 
			
		||||
 | 
			
		||||
go 1.14
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								helper.go
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								helper.go
									
									
									
									
									
								
							@ -6,8 +6,8 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 获取地址信息
 | 
			
		||||
func getAddressInfo(addressCode string, birthdayCode string) map[string]string {
 | 
			
		||||
// 检查地址码
 | 
			
		||||
func GetAddressInfo(addressCode string, birthdayCode string) map[string]string {
 | 
			
		||||
	addressInfo := map[string]string{
 | 
			
		||||
		"province": "",
 | 
			
		||||
		"city":     "",
 | 
			
		||||
@ -15,29 +15,29 @@ func getAddressInfo(addressCode string, birthdayCode string) map[string]string {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 省级信息
 | 
			
		||||
	addressInfo["province"] = getAddress(substr(addressCode, 0, 2)+"0000", birthdayCode)
 | 
			
		||||
	addressInfo["province"] = GetAddress(Substr(addressCode, 0, 2)+"0000", birthdayCode)
 | 
			
		||||
 | 
			
		||||
	// 用于判断是否是港澳台居民居住证(8字开头)
 | 
			
		||||
	firstCharacter := substr(addressCode, 0, 1)
 | 
			
		||||
	firstCharacter := Substr(addressCode, 0, 1)
 | 
			
		||||
	// 港澳台居民居住证无市级、县级信息
 | 
			
		||||
	if firstCharacter == "8" {
 | 
			
		||||
		return addressInfo
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 市级信息
 | 
			
		||||
	addressInfo["city"] = getAddress(substr(addressCode, 0, 4)+"00", birthdayCode)
 | 
			
		||||
	addressInfo["city"] = GetAddress(Substr(addressCode, 0, 4)+"00", birthdayCode)
 | 
			
		||||
 | 
			
		||||
	// 县级信息
 | 
			
		||||
	addressInfo["district"] = getAddress(addressCode, birthdayCode)
 | 
			
		||||
	addressInfo["district"] = GetAddress(addressCode, birthdayCode)
 | 
			
		||||
 | 
			
		||||
	return addressInfo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取省市区地址码
 | 
			
		||||
func getAddress(addressCode string, birthdayCode string) string {
 | 
			
		||||
func GetAddress(addressCode string, birthdayCode string) string {
 | 
			
		||||
	address := ""
 | 
			
		||||
	addressCodeInt, _ := strconv.Atoi(addressCode)
 | 
			
		||||
	year, _ := strconv.Atoi(substr(birthdayCode, 0, 4))
 | 
			
		||||
	year, _ := strconv.Atoi(Substr(birthdayCode, 0, 4))
 | 
			
		||||
	for key, val := range data.AddressCodeTimeline[addressCodeInt] {
 | 
			
		||||
		// if len(val) == 0 {
 | 
			
		||||
		// 	continue
 | 
			
		||||
@ -52,9 +52,9 @@ func getAddress(addressCode string, birthdayCode string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取星座信息
 | 
			
		||||
func getConstellation(birthdayCode string) string {
 | 
			
		||||
	monthStr := substr(birthdayCode, 4, 6)
 | 
			
		||||
	dayStr := substr(birthdayCode, 6, 8)
 | 
			
		||||
func GetConstellation(birthdayCode string) string {
 | 
			
		||||
	monthStr := Substr(birthdayCode, 4, 6)
 | 
			
		||||
	dayStr := Substr(birthdayCode, 6, 8)
 | 
			
		||||
	month, _ := strconv.Atoi(monthStr)
 | 
			
		||||
	day, _ := strconv.Atoi(dayStr)
 | 
			
		||||
	startDate := data.Constellation[month]["start_date"]
 | 
			
		||||
@ -72,17 +72,17 @@ func getConstellation(birthdayCode string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取生肖信息
 | 
			
		||||
func getChineseZodiac(birthdayCode string) string {
 | 
			
		||||
func GetChineseZodiac(birthdayCode string) string {
 | 
			
		||||
	// 子鼠
 | 
			
		||||
	start := 1900
 | 
			
		||||
	end, _ := strconv.Atoi(substr(birthdayCode, 0, 4))
 | 
			
		||||
	end, _ := strconv.Atoi(Substr(birthdayCode, 0, 4))
 | 
			
		||||
	key := (end - start) % 12
 | 
			
		||||
 | 
			
		||||
	return data.ChineseZodiac[key]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// substr 截取字符串
 | 
			
		||||
func substr(source string, start int, end int) string {
 | 
			
		||||
// Substr 截取字符串
 | 
			
		||||
func Substr(source string, start int, end int) string {
 | 
			
		||||
	r := []rune(source)
 | 
			
		||||
	length := len(r)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 身份证信息
 | 
			
		||||
type idInfo struct {
 | 
			
		||||
type IdInfo struct {
 | 
			
		||||
	AddressCode   int
 | 
			
		||||
	Abandoned     int
 | 
			
		||||
	Address       string
 | 
			
		||||
@ -24,13 +24,13 @@ type idInfo struct {
 | 
			
		||||
 | 
			
		||||
// 验证身份证号合法性
 | 
			
		||||
func IsValid(id string) bool {
 | 
			
		||||
	code, err := generateCode(id)
 | 
			
		||||
	code, err := GenerateCode(id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 检查顺序码、生日码、地址码
 | 
			
		||||
	if !checkOrderCode(code["order"]) || !checkBirthdayCode(code["birthdayCode"]) || !checkAddressCode(code["addressCode"], code["birthdayCode"]) {
 | 
			
		||||
	if !CheckOrderCode(code["order"]) || !CheckBirthdayCode(code["birthdayCode"]) || !CheckAddressCode(code["addressCode"], code["birthdayCode"]) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -40,21 +40,21 @@ func IsValid(id string) bool {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 校验码
 | 
			
		||||
	return code["checkBit"] == generatorCheckBit(code["body"])
 | 
			
		||||
	return code["checkBit"] == GeneratorCheckBit(code["body"])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取身份证信息
 | 
			
		||||
func GetInfo(id string) (idInfo, error) {
 | 
			
		||||
func GetInfo(id string) (IdInfo, error) {
 | 
			
		||||
	// 验证有效性
 | 
			
		||||
	if !IsValid(id) {
 | 
			
		||||
		return idInfo{}, errors.New("Not Valid ID card number.")
 | 
			
		||||
		return IdInfo{}, errors.New("Not Valid ID card number.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	code, _ := generateCode(id)
 | 
			
		||||
	code, _ := GenerateCode(id)
 | 
			
		||||
	addressCode, _ := strconv.Atoi(code["addressCode"])
 | 
			
		||||
 | 
			
		||||
	// 地址信息
 | 
			
		||||
	addressInfo := getAddressInfo(code["addressCode"], code["birthdayCode"])
 | 
			
		||||
	addressInfo := GetAddressInfo(code["addressCode"], code["birthdayCode"])
 | 
			
		||||
	var addressTree []string
 | 
			
		||||
	for _, val := range addressInfo {
 | 
			
		||||
		addressTree = append(addressTree, val)
 | 
			
		||||
@ -79,14 +79,14 @@ func GetInfo(id string) (idInfo, error) {
 | 
			
		||||
	// 长度
 | 
			
		||||
	length, _ := strconv.Atoi(code["type"])
 | 
			
		||||
 | 
			
		||||
	return idInfo{
 | 
			
		||||
	return IdInfo{
 | 
			
		||||
		AddressCode:   addressCode,
 | 
			
		||||
		Abandoned:     abandoned,
 | 
			
		||||
		Address:       addressInfo["province"] + addressInfo["city"] + addressInfo["district"],
 | 
			
		||||
		AddressTree:   addressTree,
 | 
			
		||||
		Birthday:      birthday,
 | 
			
		||||
		Constellation: getConstellation(code["birthdayCode"]),
 | 
			
		||||
		ChineseZodiac: getChineseZodiac(code["birthdayCode"]),
 | 
			
		||||
		Constellation: GetConstellation(code["birthdayCode"]),
 | 
			
		||||
		ChineseZodiac: GetChineseZodiac(code["birthdayCode"]),
 | 
			
		||||
		Sex:           sex,
 | 
			
		||||
		Length:        length,
 | 
			
		||||
		CheckBit:      code["checkBit"],
 | 
			
		||||
@ -105,21 +105,21 @@ func FakeId() string {
 | 
			
		||||
// sex        性别:1为男性,0为女性
 | 
			
		||||
func FakeRequireId(isEighteen bool, address string, birthday string, sex int) string {
 | 
			
		||||
	// 生成地址码
 | 
			
		||||
	addressCode := generatorAddressCode(address)
 | 
			
		||||
	addressCode := GeneratorAddressCode(address)
 | 
			
		||||
 | 
			
		||||
	// 出生日期码
 | 
			
		||||
	birthdayCode := generatorBirthdayCode(birthday)
 | 
			
		||||
	birthdayCode := GeneratorBirthdayCode(birthday)
 | 
			
		||||
 | 
			
		||||
	// 生成顺序码
 | 
			
		||||
	orderCode := generatorOrderCode(sex)
 | 
			
		||||
	orderCode := GeneratorOrderCode(sex)
 | 
			
		||||
 | 
			
		||||
	if !isEighteen {
 | 
			
		||||
		return addressCode + substr(birthdayCode, 2, 8) + orderCode
 | 
			
		||||
		return addressCode + Substr(birthdayCode, 2, 8) + orderCode
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	body := addressCode + birthdayCode + orderCode
 | 
			
		||||
 | 
			
		||||
	return body + generatorCheckBit(body)
 | 
			
		||||
	return body + GeneratorCheckBit(body)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 15位升级18位号码
 | 
			
		||||
@ -128,9 +128,9 @@ func UpgradeId(id string) (string, error) {
 | 
			
		||||
		return "", errors.New("Not Valid ID card number.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	code, _ := generateShortCode(id)
 | 
			
		||||
	code, _ := GenerateShortCode(id)
 | 
			
		||||
 | 
			
		||||
	body := code["addressCode"] + code["birthdayCode"] + code["order"]
 | 
			
		||||
 | 
			
		||||
	return body + generatorCheckBit(body), nil
 | 
			
		||||
	return body + GeneratorCheckBit(body), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user