可以将题目分成三部分考虑
1、找出错误的子网掩码(错误的子网掩码对应的ip不会算在其他组力了)
2、找到错误的ip地址
3、剩下的都是正确的ip地址,进行分类,ABCDE和私有地址其实可以划分成 uint32 的整形进行比较大小,看在哪个区间里就行

package main

import (
    "strings"
    "strconv"
    "fmt"
    "errors"
)

const IP_A_BEGIN uint32 = 0x01000000
const IP_A_END uint32 = 0x7EFFFFFF

const IP_B_BEGIN uint32 = 0x80000000
const IP_B_END uint32 = 0xBFFFFFFF

const IP_C_BEGIN uint32 = 0xC0000000
const IP_C_END uint32 = 0xDFFFFFFF

const IP_D_BEGIN uint32 = 0xE0000000
const IP_D_END uint32 = 0xEFFFFFFF

const IP_E_BEGIN uint32 = 0xF0000000
const IP_E_END uint32 = 0xFFFFFFFF

const PRIVATE_IP_10_BEGIN uint32 = 0x0A000000
const PRIVATE_IP_10_END uint32 = 0x0AFFFFFF
const PRIVATE_IP_172_BEGIN uint32 = 0xAC100000
const PRIVATE_IP_172_END uint32 = 0xAC1FFFFF
const PRIVATE_IP_192_BEGIN uint32 = 0xC0A80000
const PRIVATE_IP_192_END uint32 = 0xC0A8FFFF

func IPAddress() {
    var A,B,C,D,E,errAddress,privateAddress int
    var input, ip,mask string
    for {
        var ipSum uint32
        _, err := fmt.Scanf("%s", &input)
        if err != nil {
            break
        }
        t := strings.Split(input, "~")
        ip = t[0]
        mask = t[1]
        if !validMask(mask) {
            errAddress++
            continue
        }
        r,err := validIP(ip)
        if err != nil {
            continue
        }
        if !r {
            errAddress++
            continue
        }
        ip0, ip1, ip2, ip3, _ := IPSplit(ip)
        ipSum += uint32(ip0) << 24
        ipSum += uint32(ip1) << 16
        ipSum += uint32(ip2) << 8
        ipSum += uint32(ip3)
        if ipSum >= IP_A_BEGIN && ipSum <= IP_A_END {
            A++
        } else if ipSum >= IP_B_BEGIN && ipSum <= IP_B_END {
            B++
        } else if ipSum >= IP_C_BEGIN && ipSum <= IP_C_END {
            C++
        } else if ipSum >= IP_D_BEGIN && ipSum <= IP_D_END {
            D++
        } else if ipSum >= IP_E_BEGIN {
            E++
        }
        if (ipSum >= PRIVATE_IP_10_BEGIN && ipSum <= PRIVATE_IP_10_END) || (ipSum >= PRIVATE_IP_172_BEGIN && ipSum <= PRIVATE_IP_172_END) || (ipSum >= PRIVATE_IP_192_BEGIN && ipSum <= PRIVATE_IP_192_END) {
            privateAddress++
        }
    }
    fmt.Println(A,B,C,D,E,errAddress,privateAddress)
}

func IPSplit(ip string) (uint64,uint64,uint64,uint64,error) {
    ips := strings.Split(ip, ".")
    if len(ips) != 4 {
        return 0,0,0,0, errors.New("ip length invalid")
    }
    ip0,err := strconv.ParseUint(ips[0], 10, 8)
    if err != nil {
        return 0,0,0,0, err
    }
    ip1,err := strconv.ParseUint(ips[1], 10, 8)
    if err != nil {
        return 0,0,0,0, err
    }
    ip2,err := strconv.ParseUint(ips[2], 10, 8)
    if err != nil {
        return 0,0,0,0, err
    }
    ip3,err := strconv.ParseUint(ips[3], 10, 8)
    if err != nil {
        return 0,0,0,0, err
    }
    return ip0,ip1,ip2,ip3,nil
}

func validIP(ip string) (bool,error) {
    ip0, _, _, _, err := IPSplit(ip)
    if err != nil {
        return false, nil // 错误 ip 但是需要统计
    }
    if ip0 == 0 || ip0 == 127 {
        return false, errors.New("环回地址") // 不统计
    }
    return true, nil
}

func validMask(mask string) bool {
    p0,p1,p2,p3,err := IPSplit(mask)
    if err != nil {
        return false
    }
    // 4 个都是 0
    if p0 == 0 && p1 == 0 && p2 == 0 && p3 == 0{
        return false
    }
    // 4 个都是 255 非法
    if p0 == 255 && p1 == 255 && p2 == 255 && p3 == 255{
        return false
    }
    // 如果b取反后+1与b进行或运算,如果结果=b则说明是合法掩码,否则为非法掩码
    var b uint32 = 0
    b += uint32(p0) << 24
    b += uint32(p1) << 16
    b += uint32(p2) << 8
    b += uint32(p3)
    return (b | (^b + 1)) == b
}

func main() {
    IPAddress()
}