IP地址(IPV4)与int类型之间的转换
- 《IP地址(IPV4)与int类型之间的转换》
- 《IP地址(IPV6)与long数组之间的转换》
IP地址(IPV4)是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。IP地址(IPV4)通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。
即ip 地址(IPV4)本身就是一个32位的二进制数,只是通常被以 a.b.c.d 的形式表示而已。
二、IP地址(IPV4)为什么要转换为int类型根据前言,我们知道IP地址(IPV4)分为四段,每段都是 0~255 之间的数,每段可以用 8 位来装下它,4x8=32位,也就是可以将ip地址转为 32 位的整数。而Java中的int类型正好是32位。
那么为什么要将 IP地址(IPV4)转为数字呢?其实就是时间换空间的一种方式。如果把IP地址(IPV4)用String类型表示的话,那么会占用 7 (如0.0.0.0) 到 15 (如 255.255.255.255) 个字节,而用 int 类型表示的话只需要 4 个字节!
三、IP地址(IPV4)与int类型之间的相互转换 1.IP地址(IPV4)转换为int类型/**
* 将IP地址(IPV4)字符串转换为 int类型的数字
*
* 思路:将 IP地址(IPV4)的每一段数字转为 8 位二进制数,并将它们放在结果的适当位置上
*
* @param IP地址(IPV4) 字符串,如 127.0.0.1
* @return IP地址(IPV4) 字符串对应的 int值
*/
public static int ipv4ToInt(String ipv4_string) {
// 取 ip 的各段
String[] ipSlices = ipv4_string.split("\\.");
int result = 0;
for (int i = 0; i < ipSlices.length; i++) {
// 将 ip 的每一段解析为 int,并根据位置左移 8 位
int intSlice = Integer.parseInt(ipSlices[i]) > pos);
}
return String.join(".", ipString);
}
以 -1这个int为例,上面的无符号右移运算过程如下。
-1的原码为11111111 11111111 11111111 11111111
当i=0时,pos=0
and = ipv4_int &(255 >> pos
进行无符号右移0位运算,结果为255
当i=1时,pos=8
and = ipv4_int &(255 >> pos
进行无符号右移8位运算,结果为255
当i=2时,pos=16
and = ipv4_int (255 >> pos
进行无符号右移16位运算,结果为255
当i=3时,pos=24
and = ipv4_int &(255 >> pos
进行无符号右移24位运算,结果为255
3.测试
public static void main(String[] args) {
String ipv4_string = "255.255.255.255";
int ipv4_int = ipv4ToInt(ipv4_string);
System.out.println(ipv4_string + "对应的int值为:" + ipv4_int);
System.out.println(ipv4_int + "对应的ip值为:" + intToIpv4(ipv4_int));
}
输出结果为:
255.255.255.255对应的int值为:-1
-1对应的ip值为:255.255.255.255
四、注意
1.使用无符号右移那句是要转为0到255的正整数,如果带符号右移,则左边会补1导致结果不对。 2.文中相互转换的算法是配套的,不同的转换算法计算的 int 值可能会不一样,因为虽然都是处理 ip 的 4 个部分,但是它们的结合顺序可以不一样,因此以怎样的顺序搭配转为 int,就应该以相同的顺序解析为 String。 3.直接保存字符串,虽然可读性最好,但浪费了不少的存储空间;转换后再存储,虽然节约了存储空间,但可读性较差。该如何取舍,还是根据具体的应用场景来决定。
参考:https://mp.weixin.qq.com/s/FzAMbks0PUorZFsCFw7KTg