![左移](https://www.mkyong.com/wp-content/uploads/2013/11/lshiftLeft.gif)
在了解什么是& 0xFF
,请确保您了解以下内容:
- 按位AND运算符, link 。
- 将十六进制转换为二进制,或将十进制转换为二进制。
简而言之, & 0xFF
用于确保始终获得最后8位。 让我们看一个将IP地址与十进制数字进行相互转换的示例。
1.将IP地址转换为十进制
通常将IpAddress转换为十进制并将其存储到数据库中,以进行更好的计算和比较。
Testing IP address = 192.168.1.2
Decimal Number = 3232235778
要将192.168.1.2
转换为十进制(以10为底),公式为:
192 x (256)^3 + 168 x (256)^2 + 1 x (256)^1 + 2 (256)^0 = ?
3221225472 + 11010048 + 256 + 2 = 3232235778
PS一个标准IP是“ base 256”( 来源) 。
2.使用&0xFF将十进制转换为IP地址
为了将十进制转换回IP地址,我们使用了位移运算符,并用& 0xff
“屏蔽”它。
Java code
long ipAddress = 3232235778L;
String binary = Long.toBinaryString(ipAddress);
System.out.println(binary);
System.out.println((ipAddress>>24) & 0xFF);
System.out.println((ipAddress>>16) & 0xFF);
System.out.println((ipAddress>>8) & 0xFF);
System.out.println((ipAddress) & 0xFF);
输出量
11000000101010000000000100000010
192
168
1
2
问题是,为什么(ipAddress>>24) & 0xFF
将返回192? 让我们跳入下面的二进制位移理论:
2.1(ipAddress >> 24)和0xFF = 192
Decimal = 3232235778
Binary = 11000000 10101000 00000001 00000010
IpAddress = 192 168 1 2
(ipAddress>>24)
-------------------------->24
Binary = 00000000 00000000 00000000 11000000
(ipAddress>>24) & 0xFF
Binary = 00000000 00000000 00000000 11000000
& 0xFF = 00000000 00000000 00000000 11111111
Result = 00000000 00000000 00000000 11000000 = 192 (2^7 + 2^6)
在这种情况下,0xFF是可选的。
2.2(ipAddress >> 16)和0xFF = 168
Decimal = 3232235778
Binary = 11000000 10101000 00000001 00000010
(ipAddress>>16)
----------------->16
Binary = 00000000 00000000 11000000 10101000
(ipAddress>>16) & 0xFF
Binary = 00000000 00000000 11000000 10101000 = 49320 (2^14 + 2^15 + 2^7 + 2^5 + 2^3)
& 0xFF = 00000000 00000000 00000000 11111111
Result = 00000000 00000000 00000000 10101000 = 168
在& 0xFF
之前,您将获得49320,在& 0xFF
,您将获得正确的168。现在,您应该了解& 0xFF
的用法,它只是确保始终获得最后8位。
2.3(ipAddress >> 8)&0xFF = 1
Decimal = 3232235778
Binary = 11000000 10101000 00000001 00000010
(ipAddress>>8)
-------->8
Binary = 00000000 11000000 10101000 00000001
(ipAddress>>8) & 0xFF
Binary = 00000000 11000000 10101000 00000001 = 12625921
& 0xFF = 00000000 00000000 00000000 11111111
Result = 00000000 00000000 00000000 00000001 = 1
2.4(ipAddress)和0xFF = 2
Decimal = 3232235778
Binary = 11000000 10101000 00000001 00000010
(ipAddress)
Binary = 11000000 10101000 00000001 00000010
(ipAddress) & 0xFF
Binary = 11000000 10101000 00000001 00000010 = 3232235778
& 0xFF = 00000000 00000000 00000000 11111111
Result = 00000000 00000000 00000000 00000010 = 2
3. Java源代码
完整的Java示例来演示上述场景。
BitwiseExample.java
package com.mkyong.core;
public class BitwiseExample {
public static void main(String[] args) {
BitwiseExample obj = new BitwiseExample();
long ipAddressInLong = obj.ipToLong("192.168.1.2");
System.out.println(ipAddressInLong);
String binary = Long.toBinaryString(ipAddressInLong);
printPrettyBinary(binary);
String ipAddressInString = obj.longToIp(ipAddressInLong);
System.out.println(ipAddressInString);
}
public long ipToLong(String ipAddress) {
String[] addrArray = ipAddress.split("\\.");
long num = 0;
for (int i = 0; i < addrArray.length; i++) {
int power = 3 - i;
// 1. (192 % 256) * 256 pow 3
// 2. (168 % 256) * 256 pow 2
// 3. (2 % 256) * 256 pow 1
// 4. (1 % 256) * 256 pow 0
num += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power)));
}
return num;
}
public String longToIp(long i) {
return ((i >> 24) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + (i & 0xFF);
}
//print pretty binary code, padding left zero
private static void printPrettyBinary(String binary) {
String s1 = String.format("%32s", binary).replace(' ', '0');
System.out.format("%8s %8s %8s %8s %n",
s1.substring(0, 8), s1.substring(8, 16),
s1.substring(16, 24), s1.substring(24, 32));
}
}
输出量
3232235778
11000000 10101000 00000001 00000010
192.168.1.2
图片来源: http : //chortle.ccsu.edu/AssemblyTutorial/Chapter-12/lshiftLeft.gif
参考文献
- Java –将IP转换为十进制示例
- “&0xFF”是做什么的?
- Stackoverflow:位移的绝对入门指南?
- Stackoverflow:计算Java中的IP是否在指定范围内
- 维基百科:二进制补码
- 维基百科:按位运算
- 将基数10转换为IP
- Microsoft:IP地址