package regx import ( "encoding/json" "errors" "fmt" "git.sre.ink/go/gtool/date" "io/ioutil" "regexp" "strconv" ) // Check Perform global verification func (rr *Regx) IsIdCardCheck(id string) (bool, error) { //digit check flag, err := rr.IsValidIdCard(id) if err != nil { return flag, err } //Check the date birth := id[6:14] _, err = rr.CheckBirthdayCode(birth) if err != nil { return false, err } return true, nil } var area = make(map[string]string) // initConfig locale configuration func (rr *Regx) initConfig() { c := "./area.json" raw, err := ioutil.ReadFile(c) err = json.Unmarshal(raw, &area) if err != nil { err = fmt.Errorf("Failed to parse basic configuration file:%s\n", err.Error()) return } } // GetProvinceByIdCard get province func (rr *Regx) GetProvinceByIdCard(address string) string { rr.initConfig() address = address[:6] provincialCode := address[:3] + "000" cityCode := address[:4] + "00" return area[provincialCode] + area[cityCode] + area[address] } // IsValidCard Verify that the ID is legal func (rr *Regx) IsValidIdCard(id string) (bool, error) { if len(id) != 15 && len(id) != 18 { return false, errors.New("身份证长度不对") } return rr.CheckValidNo18(id) } // 18-digit ID verification code func (rr *Regx) CheckValidNo18(id string) (bool, error) { //string -> []byte id18 := []byte(id) nSum := 0 for i := 0; i < len(id18)-1; i++ { n, _ := strconv.Atoi(string(id18[i])) nSum += n * weight[i] } //mod gets 18-bit ID verification code mod := nSum % 11 if validValue[mod] == id18[17] { return true, nil } return false, errors.New("身份证不正确请进行核实") } // 校验身份证号格式 func (rr *Regx) IsIdCardFormat(identityCard string) bool { switch len(identityCard) { case 15: // 15位身份证号码:15位全是数字 result, _ := regexp.MatchString(`^(\d{15})$`, identityCard) return result case 18: // 18位身份证:前17位为数字,第18位为校验位,可能是数字或X result, _ := regexp.MatchString(`^(\d{17})([0-9]|X|x)$`, identityCard) return result default: //身份证位数应该为:15位 与 18位 return false } return true } // GetAgeByIdCard Get age based on ID func (rr *Regx) GetAgeByIdCard(id string) int { d := new(date.DateTime) now := d.Now().Time() birth, _ := rr.GetBirthByIdCard(id) startTime, err := d.Parse(birth) if err != nil { return 0 } if startTime.Time().Before(now) { diff := now.Unix() - startTime.Time().Unix() Age := diff / (3600 * 365 * 24) return int(Age) } return 0 } // GetBirthByIdCard get birthday func (rr *Regx) GetBirthByIdCard(id string) (string, error) { birth := id[6:14] _, err := rr.CheckBirthdayCode(birth) if err != nil { return "", err } return birth[:4] + "-" + birth[4:6] + "-" + birth[6:], nil } // GetYearByIdCard Year based on ID func (rr *Regx) GetYearByIdCard(id string) string { return id[6:14][:4] } // GetMonthByIdCard Get the month of your birthday based on your ID func (rr *Regx) GetMonthByIdCard(id string) string { return id[6:14][4:6] } // GetDayByIdCard Get birthday based on ID func (rr *Regx) GetDayByIdCard(id string) string { return id[6:14][6:] } // GetSex Get gender based on ID // Description 0 Female 1 Male 3 unknown ID card gender identification error func (rr *Regx) GetSex(id string) uint { var unknown uint = 3 sexStr := id[16:17] if sexStr == "" { return unknown } i, err := strconv.Atoi(sexStr) if err != nil { return unknown } if i%2 != 0 { return 1 } return 0 } // Convert15To18 15-digit ID card to 18-digit // 15位身份证转为18位 var weight = [17]int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2} var validValue = [11]byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'} func (rr *Regx) Convert15To18(id string) string { nLen := len(id) if nLen != 15 { return "身份证不是15位!" } id18 := make([]byte, 0) id18 = append(id18, id[:6]...) id18 = append(id18, '1', '9') id18 = append(id18, id[6:]...) sum := 0 for i, v := range id18 { n, _ := strconv.Atoi(string(v)) sum += n * weight[i] } mod := sum % 11 id18 = append(id18, validValue[mod]) return string(id18) }