题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
package main import ( "fmt" "strings" "strconv" "bufio" "os" ) func isValidIP(ip string) bool { ipSegments := strings.Split(ip, ".") for _, ipSegment := range ipSegments { if len(ipSegment) == 0 { // fmt.Printf("ip: %s, judge: %v\n", s, "False") return false } num, err := strconv.Atoi(ipSegment) if err != nil || num > 255 { return false } } return true } func isValidSubnetMask(subnetMask string) bool { subnetMaskSegments := strings.Split(subnetMask, ".") // 注意二进制下全是1或者全是0均为非法子网掩码 if subnetMask == "0.0.0.0" || subnetMask == "255.255.255.255" { return false } var bits [32]int var idx int for _, subnetMaskSegment := range subnetMaskSegments { var bit [8]int bitIdx := 7 subnetMaskSegmentNumber, _ := strconv.Atoi(subnetMaskSegment) for subnetMaskSegmentNumber > 0 { bit[bitIdx] = subnetMaskSegmentNumber % 2 subnetMaskSegmentNumber /= 2 bitIdx-- } copy(bits[idx:idx+8], bit[:]) idx += 8 } isStartOne := false for i:=31; i>=0; i-- { if bits[i] == 1 { isStartOne = true } if isStartOne && bits[i] == 0 { return false } } // fmt.Printf("mask: %s, judge: %v\n", s, "True") return true } func isBetween(ip, min, max string) bool { ipSegment := strings.Split(ip, ".") minSegment := strings.Split(min, ".") maxSegment := strings.Split(max, ".") for i:=0; i<4; i++ { ipSegmentNumber, _ := strconv.Atoi(ipSegment[i]) minSegmentNumber, _ := strconv.Atoi(minSegment[i]) maxSegmentNumber, _ := strconv.Atoi(maxSegment[i]) if ipSegmentNumber < minSegmentNumber || ipSegmentNumber > maxSegmentNumber { return false } } return true } func addressCompare(ip string) (ch byte, isPrivate bool) { minAddressOfA := "1.0.0.0" maxAddressOfA := "126.255.255.255" minAddressOfB := "128.0.0.0" maxAddressOfB := "191.255.255.255" minAddressOfC := "192.0.0.0" maxAddressOfC := "223.255.255.255" minAddressOfD := "224.0.0.0" maxAddressOfD := "239.255.255.255" minAddressOfE := "240.0.0.0" maxAddressOfE := "255.255.255.255" minPrivateAddressOfA := "10.0.0.0" maxPrivateAddressOfA := "10.255.255.255" minPrivateAddressOfB := "172.16.0.0" maxPrivateAddressOfB := "172.31.255.255" minPrivateAddressOfC := "192.168.0.0" maxPrivateAddressOfC := "192.168.255.255" if isBetween(ip, minAddressOfA, maxAddressOfA) { // fmt.Printf("ip: %s, type: %c, isPrivate: %v\n", ip, 'A', isPrivate) ch = 'A' } if isBetween(ip, minAddressOfB, maxAddressOfB) { ch = 'B' } if isBetween(ip, minAddressOfC, maxAddressOfC) { ch = 'C' } if isBetween(ip, minAddressOfD, maxAddressOfD) { // fmt.Printf("ip: %s, type: %c, isPrivate: %v\n", ip, 'D', isPrivate) ch = 'D' } if isBetween(ip, minAddressOfE, maxAddressOfE) { ch = 'E' } if isBetween(ip, minPrivateAddressOfA, maxPrivateAddressOfA) { isPrivate = true } if isBetween(ip, minPrivateAddressOfB, maxPrivateAddressOfB) { isPrivate = true } if isBetween(ip, minPrivateAddressOfC, maxPrivateAddressOfC) { isPrivate = true } return ch, isPrivate } func calculate(ss []string) { var addressOfA int var addressOfB int var addressOfC int var addressOfD int var addressOfE int var addressOfPrivate int var addressOrSubnetMaskOfErr int for _, s := range ss { pair := strings.Split(s, "~") ip, subnetMask := pair[0], pair[1] ipSegment := strings.Split(ip, ".") if ipSegment[0] == "0" || ipSegment[0] == "127" { continue } // 判断 IP 和 Mask 格式是否正确 if !isValidIP(ip) || !isValidSubnetMask(subnetMask) { addressOrSubnetMaskOfErr++ continue } ch, isPrivate := addressCompare(ip) if ch == 'A' {addressOfA++} if ch == 'B' {addressOfB++} if ch == 'C' {addressOfC++} if ch == 'D' {addressOfD++} if ch == 'E' {addressOfE++} if isPrivate {addressOfPrivate++} } fmt.Printf("%d %d %d %d %d %d %d", addressOfA, addressOfB, addressOfC, addressOfD, addressOfE, addressOrSubnetMaskOfErr, addressOfPrivate) } func main() { var ss []string inputReader := bufio.NewReader(os.Stdin) for true { line, _, _ := inputReader.ReadLine() if len(line) == 0 { break } s := string(line) ss = append(ss, s) } calculate(ss) }
// 本题输入为多行字符串,所以采用:inputReader.ReadLine()