diff --git a/Makefile b/Makefile index ffd4922..74b95db 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ fmt: go fmt ./... vet: - go vet ./..。 + go vet ./... test: go test ./... -cover -coverprofile=coverage -covermode=atomic -race -v diff --git a/id_validator_basic.go b/id_validator_basic.go new file mode 100644 index 0000000..5b3bdd3 --- /dev/null +++ b/id_validator_basic.go @@ -0,0 +1,73 @@ +package idvalidator + +import ( + "errors" + "strconv" + "time" + + "github.com/spf13/cast" +) + +// BasicIdInfo 不含地址码的身份证信息 +type BasicIdInfo struct { + Birthday time.Time + Constellation string + ChineseZodiac string + Sex int + Length int + CheckBit string +} + +// IsValidBasic 验证身份证号除地址信息之外的合法性 +func IsValidBasic(id string) bool { + code, err := generateCode(id) + if err != nil { + return false + } + + // 检查顺序码、生日码、地址码 + if !checkOrderCode(code["order"]) || !checkBirthdayCode(code["birthdayCode"]) { + return false + } + + // 15位身份证不含校验码 + if code["type"] == "15" { + return true + } + + // 校验码 + return code["checkBit"] == generatorCheckBit(code["body"]) +} + +// GetBasicInfo 获取除地址信息之外的身份证信息 +func GetBasicInfo(id string) (BasicIdInfo, error) { + // 验证有效性 + if !IsValidBasic(id) { + return BasicIdInfo{}, errors.New("invalid ID card number") + } + + code, _ := generateCode(id) + + // 生日 + cst, _ := time.LoadLocation("Asia/Shanghai") + birthday, _ := time.ParseInLocation("20060102", code["birthdayCode"], cst) + + // 性别 + sex := 1 + order, _ := strconv.Atoi(code["order"]) + if (order % 2) == 0 { + sex = 0 + } + + // 长度 + length := cast.ToInt(code["type"]) + + return BasicIdInfo{ + Birthday: birthday, + Constellation: getConstellation(code["birthdayCode"]), + ChineseZodiac: getChineseZodiac(code["birthdayCode"]), + Sex: sex, + Length: length, + CheckBit: code["checkBit"], + }, nil +} diff --git a/id_validator_basic_test.go b/id_validator_basic_test.go new file mode 100644 index 0000000..07817f8 --- /dev/null +++ b/id_validator_basic_test.go @@ -0,0 +1,36 @@ +package idvalidator + +import ( + "testing" +) + +// go test -v -cover -coverprofile=cover.out +// go tool cover -func=cover.out +// go tool cover -html=cover.out +func TestIsValidBasic(t *testing.T) { + errIds := []string{ + "44030819990110", // 号码位数不合法 + "440308199902301512", // 出生日期码不合法 + "440308199901101513", // 验证码不合法 + "610104620932690", // 出生日期码不合法 + "11010119900307867X", // 校验位不合法 + "TES12345678901 j", // 特殊字符格式不合法 + } + for _, id := range errIds { + if IsValidBasic(id) { + t.Errorf("ID must be invalid.: %s", id) + } + } +} + +func TestGetInfoBasic(t *testing.T) { + _, e1 := GetBasicInfo("440301197110292910") + if e1 != nil { + t.Errorf("`e1` must be nil.: %v", e1) + } + + _, e2 := GetBasicInfo("500154199302305886") + if e2 == nil { + t.Errorf("`e2` must not be nil.: %v", e2) + } +}