题解 | #识别有效的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()

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务