判断一个IP地址是私有地址,其原理是A,B,C三类私有地址有明确的范围,他们有各自的前缀,A类地址有8位前缀,B类地址有12位前缀, C类地址有16位前缀。本文所指的IP地址,皆是IPV4。
一个IPV4地址,由四段组成,最大值为255,一个IP地址其实就是一个32位的bit串,每8位一段。所谓私有地址,就是非注册地址,只能做内网地址。私有地址有三类,分别是
划分规则如下:
啥意思呢。就拿A类地址来说,前八位已经定下来了,就是10,后面的22位,随意变化,那么范围自然就是10.0.0.0到10.255.255.255了,B类地址前12位已经定下来了,第一个八位定为172,第二个八位的前4位定为16,他们的二进制表示是这样的
第一段的8位加上第二段的前4位,这12位是固定下来的。那么后面的20位就是可以随便变化的,而第二段的后4位即便都是1,那么第二段的最大值也只能是00011111,也就是31,所以B类地址的第二段最大值就是31
明白了私有地址的范围,我们也就好计算了。一种方法,就是根据规则对字符串进行比较,用中间的点做分割,然后逐一对每段的值进行判断,然而本文要说的是另一个思路。
我们可以把一个IP地址转成二进制,然后呢,每一类的地址的前面8,12,或16位其实是固定的,只要前面的这些位对得上,那么这个地址就是私有地址,程序用python编写,代码如下:
import socket
import struct
ip1 = 167772160
ip2 = 2886729728
ip3 = 3232235520
def isPrivateIp(ip):
#将ip地址转换成二进制的形式
binaryIp = socket.inet_aton(ip)
#将二进制转成无符号long型
numIp = struct.unpack('!L', binaryIp)[0]
#32位都是1
mark = 2**32-1
#取numIP的前16位
tag = (mark<<16) & numIp
if ip3 ==tag:
return True
#取numIP的前12位
tag = mark<<20 & numIp
if ip2 == tag:
return True
#取numIP的前8位
tag = (mark<<24) & numIp
if ip1 == tag:
return True
return False
if __name__=='__main__':
print(isPrivateIp('192.168.0.1'))
QQ交流群: 211426309