// Copyright 2019 getensh.com. All rights reserved. // Use of this source code is governed by getensh.com. package utils import ( "fmt" "strings" "unicode" "unicode/utf8" ) const ( VINLEN = 17 PLATELEN = 6 PLATENEWLEN = 7 SF = "京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新" ) func isUnknowPlateType(plateType string) bool { switch plateType { case "02": return false case "03": return false case "04": return false case "15": return false case "16": return false case "23": return false case "24": return false case "26": return false case "27": return false default: return true } } func getPlateType(plateNo string) string { switch { case strings.HasPrefix(plateNo, "使"): return "03" case strings.HasSuffix(plateNo, "使"): return "03" // 领馆汽车 case strings.HasSuffix(plateNo, "领"): return "04" case strings.HasSuffix(plateNo, "挂"): return "15" case strings.HasSuffix(plateNo, "学"): return "16" case strings.HasSuffix(plateNo, "警"): return "23" case strings.HasSuffix(plateNo, "港"): return "26" case strings.HasSuffix(plateNo, "澳"): return "27" default: return "" } } func isSupportPlateType(plateType string) bool { switch plateType { case "01": return true case "02": return true case "03": return true case "04": return true case "05": return true case "06": return true case "07": return true case "08": return true case "09": return true case "10": return true case "11": return true case "12": return true case "13": return true case "14": return true case "15": return true case "16": return true case "17": return true case "20": return true case "21": return true case "22": return true case "23": return true case "24": return true case "25": return true case "26": return true case "27": return true case "51": return true case "52": return true case "99": return true default: return false } return false } func isContainSpecialCharactor(plateNumber []byte) bool { if strings.Contains(string(plateNumber), "I") || strings.Contains(string(plateNumber), "O") { return true } if getPlateType(string(plateNumber)) != "02" { return false } for _, v := range plateNumber { if (v >= 48 && v <= 57) || (v >= 65 && v <= 90) || (v >= 97 && v <= 122) { continue } return true } return false } func ParsePlate(plate string) (string, string) { var index int for i, r := range plate { if !unicode.Is(unicode.Scripts["Han"], r) { index = i break } } sf := plate[0:index] hphm := plate[index:] return sf, hphm } func CheckPlateNoFormat(plateNo *string, plateType string) (string, error) { *plateNo = strings.TrimSpace(*plateNo) *plateNo = strings.ToUpper(*plateNo) if plateType != "" { if !isSupportPlateType(plateType) { return "", fmt.Errorf( "参数错误,不支持的车牌类型") } } // 判断车牌号码合法性 sf, plateNumber := ParsePlate(*plateNo) if len(sf) == 0 { if strings.HasSuffix(*plateNo, "使") { return "03", nil } return plateType, fmt.Errorf( "请求参数格式不对,车牌号码格式不正确") } else if sf != "使" { if !strings.Contains(SF, sf) { return plateType, fmt.Errorf("请求参数格式不对,不支持的省份") } } // 检查车牌是否包含特殊字符 if isContainSpecialCharactor([]byte(plateNumber)) { return plateType, fmt.Errorf( "请求参数格式不对,车牌号码包含特殊字符") } plateLen := utf8.RuneCountInString(plateNumber) if plateType == "" && plateLen == PLATENEWLEN { if plateNumber[1] > 64 && plateNumber[1] < 91 { plateType = "52" } else if plateNumber[PLATENEWLEN-1] > 64 && plateNumber[PLATENEWLEN-1] < 91 { plateType = "51" } else { return plateType, fmt.Errorf( "请求参数格式不对,新能源汽车车牌格式不正确") } } count := 0 for _, v := range plateNumber { if 64 < v && v < 91 { count++ } } if strings.HasPrefix(*plateNo, "使") || strings.HasSuffix(*plateNo, "使") { if plateType == "" { return "03", nil } else { if plateType != "03" { return "", fmt.Errorf( "请求参数格式不对,车牌和车牌类型不匹配") } return plateType, nil } } else if strings.HasSuffix(*plateNo, "领") { if plateType == "" { return "04", nil } else { if plateType != "04" { return "", fmt.Errorf( "请求参数格式不对,车牌和车牌类型不匹配") } return plateType, nil } } else if plateType == "51" || plateType == "52" { if count > 3 { return plateType, fmt.Errorf( "请求参数格式不对,新能源车牌号码超过3个字母") } else if plateLen != PLATENEWLEN { return plateType, fmt.Errorf( "请求参数格式不对,新能源车牌号码长度不正确") } else { if plateNumber[1] > 64 && plateNumber[1] < 91 { if plateType != "52" { return plateType, fmt.Errorf( "请求参数格式不对,新能源车牌号码和车牌类型不匹配") } } else if plateNumber[PLATENEWLEN-1] > 64 && plateNumber[PLATENEWLEN-1] < 91 { if plateType != "51" { return plateType, fmt.Errorf( "请求参数格式不对,新能源车牌号码和车牌类型不匹配") } } else { return plateType, fmt.Errorf( "请求参数格式不对,新能源汽车车牌格式不正确") } } } else { if count > 3 { return plateType, fmt.Errorf( "请求参数格式不对,车牌号码超过3个字母") } else if plateLen != PLATELEN { return plateType, fmt.Errorf("请求参数格式不对,车牌号码长度不正确") } } if strings.Contains("0123456789", plateNumber[0:1]) { return plateType, fmt.Errorf( "请求参数格式不对,号牌号码第一位不能为数字") } if plateType == "51" || plateType == "52" { return plateType, nil } if plateType != "" && isUnknowPlateType(plateType) { return plateType, nil } plateTypeNew := getPlateType(*plateNo) if plateType != "" && plateTypeNew != plateType { return plateType, fmt.Errorf( "请求参数格式不对,车牌号码和车牌类型不匹配") } return plateTypeNew, nil } func VehicleDefaultPlateType(plateNo *string) (plateType string, err error) { *plateNo = strings.TrimSpace(*plateNo) *plateNo = strings.ToUpper(*plateNo) sf, plateNumber := ParsePlate(*plateNo) if len(sf) == 0 { if strings.HasSuffix(*plateNo, "使") { return "03", nil }else{ return "",nil } } plateLen := utf8.RuneCountInString(plateNumber) if plateLen == PLATENEWLEN { if plateNumber[1] > 64 && plateNumber[1] < 91 { plateType = "52" return plateType, nil } else if plateNumber[PLATENEWLEN-1] > 64 && plateNumber[PLATENEWLEN-1] < 91 { plateType = "51" return plateType, nil } else { return plateType, fmt.Errorf( "参数格式不对,新能源汽车车牌格式不正确") } } else if plateLen == PLATELEN { plateType = getPlateType(*plateNo) return plateType, nil } else { return plateType, fmt.Errorf("参数格式不对,车牌长度不正确") } return plateType, nil }