Рубрики
Без рубрики

Java – Преобразование IP-адреса в десятичное число

– Java – Преобразование IP-адреса в десятичное число

В этом уроке мы покажем вам, как преобразовать IP-адрес в его десятичный эквивалент в Java и наоборот. Для примеров:

255.255.255.255  <->  4294967295
192.168.1.2      <->  3232235778

1. IP-адрес в десятичный

Мы покажем вам два способа преобразования IP-адреса в десятичное число

  1. Нормальная мощность 256
  2. Смещение бита

1.1 Первый пример – Мощность 256 IP-адрес “базовый 256”, для преобразования 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
  public long ipToLong(String ipAddress) {

	String[] ipAddressInArray = ipAddress.split("\\.");

	long result = 0;
	for (int i = 0; i < ipAddressInArray.length; i++) {

		int power = 3 - i;
		int ip = Integer.parseInt(ipAddressInArray[i]);
		result += ip * Math.pow(256, power);

	}

	return result;
  }

Некоторые разработчики предпочитают использовать модульные, подобные этому

result += (Integer.parseInt(ipAddressInArray[i]) % 256 * Math.pow(256, power));

1.2 Второй пример – Сдвиг битов Просмотрите график сдвига двоичных битов ниже:

  public long ipToLong(String ipAddress) {
		
	long result = 0;
		
	String[] ipAddressInArray = ipAddress.split("\\.");

	for (int i = 3; i >= 0; i--) {
			
		long ip = Long.parseLong(ipAddressInArray[3 - i]);
			
		//left shifting 24,16,8,0 and bitwise OR
			
		//1. 192 << 24
		//1. 168 << 16
		//1. 1   << 8
		//1. 2   << 0
		result |= ip << (i * 8);
		
	}

	return result;
  }
192         00000000 00000000 00000000 11000000 
-----------------------------------------------
192 << 24   11000000 00000000 00000000 00000000 
Result      00000000 00000000 00000000 00000000 
Result |=   11000000 00000000 00000000 00000000 

168         00000000 00000000 00000000 10101000 
-----------------------------------------------
168 << 16   00000000 10101000 00000000 00000000 
Result	    11000000 00000000 00000000 00000000 
Result |=   11000000 10101000 00000000 00000000

1           00000000 00000000 00000000 00000001 
-----------------------------------------------
1   << 8    00000000 00000000 00000001 00000000 
Result	    11000000 10101000 00000000 00000000 
Result |=   11000000 10101000 00000001 00000000

2           00000000 00000000 00000000 00000010 
-----------------------------------------------
2 << 0      00000000 00000000 00000000 00000010 
Result	    11000000 10101000 00000001 00000000 
Result |=   11000000 10101000 00000001 00000010

Преобразуйте окончательный двоичный код в десятичный с помощью ручного вычисления 🙂 ~

Result      11000000 10101000 00000001 00000010
index       0 - 31, start from right.
      	    31(1),30(1),29,28,27,26,25,24,23(1),22,21(1),20,19(1),18,17,16,15,14,13,12,11,10,9,8(1),7,6,5,4,3,2,1(1),0
Decimal     1x2^31 + 1x2^30 + 1x2^23 + 1x2^21 + 1x2^19 + 1x2^8 + 1x2^1
            2147483648 + 1073741824 + 8388608 + 2097152 + 524288 + 256 + 2
            3232235778

2. Десятичное число в IP-адрес

Мы покажем вам два примера сдвига битов и маскировки “0xff” для преобразования десятичного числа обратно в IP-адрес. Сдвиг битов очень трудно объяснить словами, лучше рассмотреть двоичные потоки ниже:

2.1 Первый пример.

  //ip = 3232235778
  public String longToIp(long ip) {
	StringBuilder result = new StringBuilder(15);

	for (int i = 0; i < 4; i++) {
		
		result.insert(0,Long.toString(ip & 0xff));

		if (i < 3) {
			sb.insert(0,'.');
		}

		ip = ip >> 8;
	}
	return result.toString();
  }

Просмотрите потоки смещения битов:

3232235778		11000000 10101000 00000001 00000010

<>
-----------------------------------------------------------
ip      		11000000 10101000 00000001 00000010 
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 00000010 = 2
Result Append           .2
                                 -------------------------> 8
ip >> 8			00000000 11000000 10101000 00000001 {off 00000010}

<>
-----------------------------------------------------------
ip      		00000000 11000000 10101000 00000001
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 00000001 = 1
Result Append           1.2
                                          ----------------> 8
ip >> 8			00000000 00000000 11000000 10101000 {off 00000001}

<>
-----------------------------------------------------------
ip      		00000000 00000000 11000000 10101000
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 10101000 = 168
Result Append           168.1.2
                                                   -------> 8
ip >> 8			00000000 00000000 00000000 11000000 {off 10101000}

<>
-----------------------------------------------------------
ip      		00000000 00000000 00000000 11000000
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 11000000 = 192
Result Append           192.168.1.2
                                                            -----------> 8
ip >> 8			00000000 00000000 00000000 00000000 {off 11000000}

2.2 Второй пример.

  //ip = 3232235778
  public String longToIp(long ip) {

	return ((ip >> 24) & 0xFF) + "." 
		+ ((ip >> 16) & 0xFF) + "." 
		+ ((ip >> 8) & 0xFF) + "." 
		+ (ip & 0xFF);

  }
3232235778		11000000 10101000 00000001 00000010

1. (ip >> 24) & 0xFF
-----------------------------------------------------------
ip      		11000000 10101000 00000001 00000010 
                                                   -------------------------------------> 24
ip >> 24                00000000 00000000 00000000 11000000 {off 10101000 00000001 00000010}  
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 11000000 = 192

2. (ip >> 16) & 0xFF
-----------------------------------------------------------
ip      		11000000 10101000 00000001 00000010 
                                          -------------------------------------> 16
ip >> 16                00000000 00000000 11000000 10101000 {off 00000001 00000010}  
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 10101000 = 168

3. (ip >> 8) & 0xFF
-----------------------------------------------------------
ip      		11000000 10101000 00000001 00000010 
                                 --------------------------------------> 8
ip >> 24                00000000 11000000 10101000 00000001 {off 00000010}  
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 00000001 = 1

4. ip & 0xFF
-----------------------------------------------------------
ip      		11000000 10101000 00000001 00000010 
& 0xff			00000000 00000000 00000000 11111111 
Result                  00000000 00000000 00000000 00000010 = 2

3. Исходный код Java

Полный пример Java для демонстрации описанного выше сценария:

package com.mkyong.core;

public class JavaBitwiseExample {

	public static void main(String[] args) {

		JavaBitwiseExample obj = new JavaBitwiseExample();

		System.out.println("iptoLong  : " + obj.ipToLong("192.168.1.2"));
		System.out.println("iptoLong2 : " + obj.ipToLong2("192.168.1.2"));

		System.out.println("longToIp  : " + obj.longToIp(3232235778L));
		System.out.println("longToIp2 : " + obj.longToIp2(3232235778L));

	}

	// example : 192.168.1.2
	public long ipToLong(String ipAddress) {

		// ipAddressInArray[0] = 192
		String[] ipAddressInArray = ipAddress.split("\\.");

		long result = 0;
		for (int i = 0; i < ipAddressInArray.length; i++) {

			int power = 3 - i;
			int ip = Integer.parseInt(ipAddressInArray[i]);

			// 1. 192 * 256^3
			// 2. 168 * 256^2
			// 3. 1 * 256^1
			// 4. 2 * 256^0
			result += ip * Math.pow(256, power);

		}

		return result;

	}

	public long ipToLong2(String ipAddress) {

		long result = 0;

		String[] ipAddressInArray = ipAddress.split("\\.");

		for (int i = 3; i >= 0; i--) {

			long ip = Long.parseLong(ipAddressInArray[3 - i]);

			// left shifting 24,16,8,0 and bitwise OR

			// 1. 192 << 24
			// 1. 168 << 16
			// 1. 1 << 8
			// 1. 2 << 0
			result |= ip << (i * 8);

		}

		return result;
	}

	public String longToIp(long i) {

		return ((i >> 24) & 0xFF) + 
                   "." + ((i >> 16) & 0xFF) + 
                   "." + ((i >> 8) & 0xFF) + 
                   "." + (i & 0xFF);

	}

	public String longToIp2(long ip) {
		StringBuilder sb = new StringBuilder(15);

		for (int i = 0; i < 4; i++) {

			// 1. 2
			// 2. 1
			// 3. 168
			// 4. 192
			sb.insert(0, Long.toString(ip & 0xff));

			if (i < 3) {
				sb.insert(0, '.');
			}

			// 1. 192.168.1.2
			// 2. 192.168.1
			// 3. 192.168
			// 4. 192
			ip = ip >> 8;

		}

		return sb.toString();
	}

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

Выход

iptoLong  : 3232235778
iptoLong2 : 3232235778
longToIp  : 192.168.1.2
longToIp2 : 192.168.1.2

Рекомендации

  1. Пример Java и 0xff
  2. побитовый ИЛИ пример
  3. Преобразование базы 10 в ip
  4. Корпорация Майкрософт: IP Адресация
  5. Википедия: сила двух
  6. Википедия: Побитовая операция
  7. Stackoverflow: преобразование ip-адреса в десятичный и наоборот
  8. Stackoverflow: Руководство для начинающих по сдвигу битов?

Оригинал: “https://mkyong.com/java/java-convert-ip-address-to-decimal-number/”