From f624993476640a6ea5e08412092b99bd7a2eab8d Mon Sep 17 00:00:00 2001 From: zu1k Date: Mon, 28 Sep 2020 08:26:08 +0800 Subject: [PATCH] better ValidIP --- internal/app/parse.go | 42 ++++++------ internal/tools/ipparser.go | 118 +++++---------------------------- internal/tools/iptools_test.go | 22 ++---- 3 files changed, 48 insertions(+), 134 deletions(-) diff --git a/internal/app/parse.go b/internal/app/parse.go index 05987b4..9a2f957 100644 --- a/internal/app/parse.go +++ b/internal/app/parse.go @@ -44,33 +44,37 @@ func ParseIPs(ips []string) { db1 = nil } for _, ip := range ips { - if tools.ValidIP4(ip) { + v := tools.ValidIP(ip) + switch v { + case tools.ValidIPv4: result := db0.Find(ip) fmt.Println(formatResult(ip, result)) - } else if tools.ValidIP6(ip) && db1 != nil { - result := db1.Find(ip) - fmt.Println(formatResult(ip, result)) - } else { + case tools.ValidIPv6: + if db1 != nil { + result := db1.Find(ip) + fmt.Println(formatResult(ip, result)) + } + default: fmt.Println(ReplaceIPInString(ip)) } } } func RemoveRepeatedElement(arr []string) (newArr []string) { - newArr = make([]string, 0) - for i := 0; i < len(arr); i++ { - repeat := false - for j := i + 1; j < len(arr); j++ { - if arr[i] == arr[j] { - repeat = true - break - } - } - if !repeat { - newArr = append(newArr, arr[i]) - } - } - return + newArr = make([]string, 0) + for i := 0; i < len(arr); i++ { + repeat := false + for j := i + 1; j < len(arr); j++ { + if arr[i] == arr[j] { + repeat = true + break + } + } + if !repeat { + newArr = append(newArr, arr[i]) + } + } + return } func ReplaceIPInString(str string) (result string) { diff --git a/internal/tools/ipparser.go b/internal/tools/ipparser.go index b39c473..69c459e 100644 --- a/internal/tools/ipparser.go +++ b/internal/tools/ipparser.go @@ -1,6 +1,7 @@ package tools import ( + "net" "regexp" "strings" ) @@ -19,40 +20,6 @@ func init() { ipv6re = regexp.MustCompile(`fe80:(:[0-9a-fA-F]{1,4}){0,4}(%\w+)?|([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?::(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?`) } -func ValidIP4(IP string) bool { - arr := strings.Split(IP, ".") - if len(arr) != 4 { - return false - } - for _, elem := range arr { - if elem == "" { - return false - } - if len(elem) > 1 && elem[0] == '0' { - return false - } - num := 0 - for _, c := range elem { - if c >= '0' && c <= '9' { - num = num*10 + int(c-'0') - } else { - return false - } - } - if num > 255 { - return false - } - } - return true -} - -func ValidIP6Re(str string) bool { - str = strings.Trim(str, " ") - return ipv6re0.MatchString(str) - - //return isIPV6(str) -} - func GetIP4FromString(str string) []string { str = strings.Trim(str, " ") return ipv4re.FindAllString(str, -1) @@ -63,74 +30,25 @@ func GetIP6FromString(str string) []string { return ipv6re.FindAllString(str, -1) } -//IPV6地址的判断: -//1. 用“:”分割字符串,若长度不等于8,则return Neither -//2. 遍历每一个数组的每一个元素,若元素的长度大于4,则return Neither -//3. 判断每一个元素的字符,若出现非0-9,A-F的字符,则return Neither -func ValidIP6(IP string) bool { - IP = strings.ToUpper(IP) - n := len(IP) - if n > 39 || n == 0 { - return false - } +const ( + ValidIPv4 = iota + ValidIPv6 + InvalidIP +) - // 以 ":" 结尾 但是只有一个 - if strings.HasSuffix(IP, ":") && !strings.HasSuffix(IP, "::") { - return false - } - // 如果"::" 有两个以上 - if strings.Count(IP, "::") > 1 { - return false - } - // 如果 ":" 有8个以上 - if strings.Count(IP, ":") > 8 { - return false - } - tmp := strings.Split(IP, ":") - // 如果有ipv4, 则返回真, 前面的部分未校验。 - if ValidIP4(tmp[len(tmp)-1]) { - return true - } - if strings.Contains(IP,"::") { - var count int - for _, v := range tmp { - if v != "" { - count++ - continue - } - } - if count == 8 { - return false +type Valid int + +func ValidIP(IP string) (v Valid) { + for i := 0; i < len(IP); i++ { + switch IP[i] { + case '.': + v = ValidIPv4 + case ':': + v = ValidIPv6 } } - - // 对每个元素进行遍历 - for k := 0; k < n-1; { - if IP[k] == ':' { - k++ - continue - } else if valid(IP[k]) { - var bits int - for valid(IP[k]) { - k++ - bits++ - if bits > 4 { - return false - } - if k == n { - break - } - } - - } else { - return false - } + if ip := net.ParseIP(IP); ip != nil { + return v } - - // 到了这一步, 可以确定是ipv6 - return true + return InvalidIP } - -func valid(i uint8) bool { - return (i >= 'A' && i <= 'F') || (i >= '0' && i <= '9') -} \ No newline at end of file diff --git a/internal/tools/iptools_test.go b/internal/tools/iptools_test.go index 04a2961..38ed08e 100644 --- a/internal/tools/iptools_test.go +++ b/internal/tools/iptools_test.go @@ -8,7 +8,7 @@ import ( func TestIP4Re(t *testing.T) { str := "aaa1.1.11.23a36.36.32.200" fmt.Println(GetIP4FromString(str)) - fmt.Println(ValidIP4(str)) + ValidIP(str) } func TestValidIP6(t *testing.T) { @@ -58,31 +58,23 @@ func TestValidIP6(t *testing.T) { } for _, i := range ipv6Valid { - if !ValidIP6(i) { + if v := ValidIP(i); v == InvalidIP { t.Log("valid:", i) } } for _, i := range ipv6Invalid { - if ValidIP6(i) { + if v := ValidIP(i); v != InvalidIP { t.Log("invalid:", i) } } } -func BenchmarkValidIP6Re(b *testing.B) { +func BenchmarkValidIP6STD(b *testing.B) { b.ResetTimer() origin := "::ffff:135.75.43.52" - for i:=0; i