Java and “& 0xFF” example

lshiftLeft

Before you understand what is & 0xFF, make sure you know following stuffs :

  1. Bitwise AND operator, link.
  2. Converts hex to/from binary, and decimal to/from binary.

In short, & 0xFF is used to make sure you always get the last 8 bits. Let’s see an example to convert an IP address to/from decimal number.

1. Convert IP Address To Decimal

It’s a common practice to convert IpAddress to decimal and store it into database for better calculation and comparison.


Testing IP address = 192.168.1.2
Decimal Number     = 3232235778

To convert 192.168.1.2 to decimal (base 10) the formula is:


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. Convert Decimal to IP Address, with & 0xFF

To convert decimal back to an IP address, we use bit shifting operator and “mask” it with & 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);

Output


11000000101010000000000100000010
192
168
1
2

The question is why (ipAddress>>24) & 0xFF will return 192? Let dive into the binary bit shifting theory below :

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)

In this case, the 0xFF is optional.

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

Before & 0xFF, you get 49320, after & 0xFF, you get the correct 168. Now, you should understand the usage of & 0xFF, it just makes sure you always get the last 8 bits.

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 Source Code

Full Java example to demonstrate above scenario.

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));
  }

}

Output


3232235778
11000000 10101000 00000001 00000010 
192.168.1.2

Photo Credit : http://chortle.ccsu.edu/AssemblyTutorial/Chapter-12/lshiftLeft.gif

References

  1. Java – Convert IP to Decimal example
  2. What does “& 0xFF” do?
  3. Stackoverflow : Absolute Beginner’s Guide to Bit Shifting?
  4. Stackoverflow : Calculate whether an ip is in a specified range in java
  5. Wikipedia : Two’s complement
  6. Wikipedia : Bitwise operation
  7. Convert base 10 to ip
  8. Microsoft : IP Addressing

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
MrfksIv
Guest
MrfksIv

This was very helpful while trying to understand how bufferedImages in Java work! Thanks a lot

niranga sandaruwan
Guest
niranga sandaruwan

really helpful article.one of the best programming tutorial site i have seen so far.keep up your works.

Rasmita Patra
Guest
Rasmita Patra

nice article with clear explanation…..

Apoorva
Guest
Apoorva

Thank you, it was very helpful

Nik
Guest
Nik

Perfect. Thanks :)

uNiverselEgacy
Guest
uNiverselEgacy

Should mention that & 0xFF is also helpful to prevent sign extension.
int i = (byte)0xAB;// i == -85
int i = (byte)0xAB & 0xFF; // i == 171

Suraj
Guest
Suraj

The reason why binaryIP>>24=192 is because when we convert IP address to decimal we are actually doing


192 * (256)^3 = 192 * (2^8)^3= 192 * (2^24)

So, we are, basically, left shifting by 24 places here. Hence, right shifting 24 places gives the original result

Ecka
Guest
Ecka

thank you for a good and educational article