Пример Java и «& 0xFF»
Прежде чем вы поймете, что такое& 0xFF
, убедитесь, что вы знаете следующие вещи:
-
Побитовый оператор И,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
P.S A standard IP is “base 256”, source.
2. Преобразовать десятичное число в IP-адрес с & 0xFF
Чтобы преобразовать десятичное число обратно в IP-адрес, мы используем оператор битового сдвига и «маскируем» его с помощью& 0xff
.
Java-код
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.example.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