阅读本文前,细致浏览此文以及粗略速览ipv4和无类域间路由效果更佳
- 本文涉及算法很简单,更多更有价值之处是此间过程和来龙去脉.
前言
IPV4由4个Byte组成,每个Byte有8个Bit,每个Bit有0/1两种情况,也即32位0/1字符串(IPV6由128位组成);但为了显示直观方便记忆,会将4个Byte分开,将每个Byte的值转成10进制,中间用"."拼接,也就成了平时常见的IPV4地址(这样也不太容易记忆,于是后来就用字符(域名,例如:www.dashen.tech
)来表示IP地址,每次请求时,通过DNS服务器,将字符(域名)解析成IP地址)
科普一下:把一个比特位Bit想象成一个坑,这个坑里只能放0或者1;一个字节Byte有8个比特位,则一个字节可以表征多少种不同情况?  很显然,根据乘法原理,是2x2x2x2x2x2x2x2即2的8次方即256种情况,中学学过二进制与十进制的转换,二进制00000000和11111111之间的256个不同值,对应十进制0到255.
于是,对于任意一串32位的二进制数,都可以转换为ipv4的形式,
如对"01101001 01010001 01111101 00101010",
可以分别计算每段对应的十进制数字,中间用"."分隔,
即105.81.125.42
对于IDC部门,划分到的IP地址是一个区间,如从上面的"01101001 01010001 01111101 00101010"(记为a),到"01101001 01010001 01111111 00101000"(记为b),
转换为ipv4即是"105.81.125.42"到105.81.127.40",
Step1:理论基础
那问题来了,如何判断某个ipv4地址,如"105.81.126.188",在不在这个区间范围内?
制定这套规则,做出这套转换的人类,当然能判断得出,但对于计算机,变成ipv4这个鬼样子格式,已经无法"一眼识别".
解决办法也很直观,即将ipv4格式转化为原本的二进制,如对"105.81.126.188",其对应的二进制值为"01101001 01010001 01111110 10111100"(记为c);此时即可以判断,c是否在[a,b]区间范围内.
但人类还是不习惯二进制比较大小,于是会将a,b,c全部转为10进制再做比较,
对于a对应的十进制数为1766948138,b为1766948648,
c为1766948540,现在,人类能够读懂,c在[a,b]之间.
进制转换可借助此网站快速实现,戳此直达 (注意去掉中间可能存在的空格)
具体到代码层面,可借助位运算符实现快速进制转换,
package main
import (
"strings"
"strconv"
"fmt"
)
func main() {
rs := CidrToInt("105.81.126.188")
fmt.Println(rs)
}
func CidrToInt(ip string) uint64 {
ipSegement := strings.Split(ip, ".")
segment1, _ := strconv.ParseUint(ipSegement[0], 10, 64)
segment2, _ := strconv.ParseUint(ipSegement[1], 10, 64)
segment3, _ := strconv.ParseUint(ipSegement[2], 10, 64)
segment4, _ := strconv.ParseUint(ipSegement[3], 10, 64)
intip := uint64(0)
intip = intip + (segment1