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


全部评论

相关推荐

05-29 20:34
门头沟学院 C++
KarlAllen:得做好直接春招的准备。学历差的话,一是面试要求会比学历好的严格不少,二是就算面试通过了也会被排序。总之暑期和秋招对于学历差的就是及其不友好
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务