题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
注意:
1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
此条件应理解为,只要ip是类似于【0.*.*.*】和【127.*.*.*】的IP地址,不考虑子网掩码是否合法,直接将其归类为不计数ip,跳过即可。
package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func main() { inLines := bufio.NewScanner(os.Stdin) var in []string for inLines.Scan() { inStr := inLines.Text() in = append(in, inStr) } var ( ipArr, subnetArr []int out [7]int errIP, errSubnet bool ) for _, v := range in { ipAndSubnet := strings.Split(v, "~") if len(ipAndSubnet) != 2 { out[5]++ continue } ipArr, errIP = stringArrToIntArr(strings.Split(ipAndSubnet[0], ".")) subnetArr, errSubnet = stringArrToIntArr(strings.Split(ipAndSubnet[1], ".")) if errIP || errSubnet { out[5]++ continue } if !isInIPRange(ipArr) { out[5]++ continue } if noCountIP(ipArr[0]) { continue } if !isInSubnetRange(subnetArr) { out[5]++ continue } if !isLegalSubnet(subnetArr) { out[5]++ continue } if isPrivateIP(ipArr) { out[6]++ } class := belongIPClass(ipArr[0]) if class == 0 { continue } class-- out[class]++ } fmt.Printf("%d %d %d %d %d %d %d\n", out[0], out[1], out[2], out[3], out[4], out[5], out[6]) } // 所有的IP地址划分为 A,B,C,D,E五类 // A类地址从1.0.0.0到126.255.255.255; // B类地址从128.0.0.0到191.255.255.255; // C类地址从192.0.0.0到223.255.255.255; // D类地址从224.0.0.0到239.255.255.255; // E类地址从240.0.0.0到255.255.255.255 // 私有ip // 从10.0.0.0到10.255.255.255 // 从172.16.0.0到172.31.255.255 // 从192.168.0.0到192.168.255.255 // 类似于【0.*.*.*】和【127.*.*.*】的IP地址 // 不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略 // 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。 // 是否是不合法ip // 是否是不计数ip // ip属于 A B C D E 哪一类 // ip是否属于私有ip // 子网掩码是否非法一:超过范围 // 子网掩码是否非法二:前面全是1后面全是0 func isInRange(in []int, min, max int) bool { if min > max { min, max = max, min } for _, v := range in { if v < min || v > max { return false } } return true } func isInIPRange(in []int) bool { if len(in) != 4 { return false } return isInRange(in, 0, 255) } func isPrivateIP(in []int) bool { if len(in) != 4 { fmt.Println("Shouldn't happen!") } if in[0] == 10 { return true } if in[0] == 172 && in[1] > 15 && in[1] < 32 { return true } if in[0] == 192 && in[1] == 168 { return true } return false } func isInSubnetRange(in []int) bool { if len(in) != 4 { return false } if in[0] == 0 { return false } return isInRange(in, 0, 255) } func isLegalSubnet(in []int) bool { var ( flag bool ) for _, v := range in { if flag && v != 0 { return false } if v != 0 && v != 128 && v != 192 && v != 224 && v != 240 && v != 248 && v != 252 && v != 254 && v != 255 { return false } if v == 255 && !flag { continue } if v == 255 && flag { return false } if v == 0 || v == 128 || v == 192 || v == 224 || v == 240 || v == 248 || v == 252 || v == 254 { flag = true } } if in[0] == 0 { return false } if in[len(in)-1] == 255 { return false } return true } // A:1 B:2 C:3 D:4 E:5 // 0表示:类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略 func belongIPClass(in int) int { if in >= 1 && in < 127 { return 1 } if in > 127 && in < 192 { return 2 } if in >= 192 && in < 224 { return 3 } if in >= 224 && in < 240 { return 4 } if in >= 240 && in < 256 { return 5 } return 0 } func stringArrToIntArr(stringArr []string) (intArr []int, errFlag bool) { for _, v := range stringArr { if v == "" { return nil, true } iv, _ := strconv.Atoi(v) intArr = append(intArr, iv) } return } func noCountIP(in int) bool { if in == 127 || in == 0 { return true } return false }