Я создаю небольшое приложение для своего телефона Android. Мой опыт не в компьютерной науке
но я знаком с C/С++ и некоторыми концепциями развития. Теперь я пытался отобразить IP-адрес
моего телефона. И в соответствии с рекомендациями Android я использовал метод getIpAddress()
, который возвращает
целое число.
Затем, посмотрев в stackoverflow, я увидел решение, размещенное здесь:
IP-адрес Android с java
который был отправлен Paul Ferguson
, и я копирую его здесь:
String ipString = String.format(
"%d.%d.%d.%d",
(ip & 0xff),
(ip >> 8 & 0xff),
(ip >> 16 & 0xff),
(ip >> 24 & 0xff));
ip
- это переменная типа int
, которая содержит ip-адрес. Может ли кто-нибудь объяснить мне, как это работает? Обратите внимание, что мои навыки java довольно вводные.
Благодаря комментариям @Joop Eggen позволяет сказать, что у нас есть целое число ip-адресов -926414400
Вот как работает код:
IP fileds <1> . <2> . <3> . <4>
everything is done using the bitwise (and) operation this
means that all operations are made vertically bit by bit
field <1>
ipint = 11001000 11001000 00001001 11000000
0xff = 00000000 00000000 00000000 11111111
------------------------------------
<1> = 00000000 00000000 00000000 11000000
which is equal to 192
Field <2> first we do a shift by 8 bits since
the >> operator takes precedence over the & operator
same for fields <3> and <4>
shift by 8 bits ipint now becomes
ipint = 00000000 11001000 11001000 00001001
0xff = 00000000 00000000 00000000 11111111
------------------------------------
<2> = 00000000 00000000 00000000 00001001
which is equal to 9
For field <3> shift by 16 bits ipint becomes
ipint = 00000000 00000000 11001000 11001000
0xff = 00000000 00000000 00000000 11111111
------------------------------------
<3> = 00000000 00000000 00000000 11001000
which is 200
For field <4> shift by 24 bits ipint becomes
ipint = 00000000 00000000 00000000 11001000
0xff = 00000000 00000000 00000000 11111111
------------------------------------
<4> = 00000000 00000000 00000000 11001000
which is 200
So the ip is 192.9.200.200
Существует два стандарта: IP v4 с использованием 4 байтов, а новый все еще не слишком широко распространен IP v6 с большим количеством байтов.
Теперь в вашем случае IP v4 4 байта могут содержать целое число Java или просто каждый указанный байт.
Кстати, URL-адреса могут использовать IP-номер как 4 байтовых значения, либо как одно целое число:
http://3232235778/
http://210.43.98.51/
(Я не преобразовал или не проверял числа.)
В коде используется трюк, переводящий int в long, по мере того, как целые числа java подписываются; самый левый бит равен 1, не означает очень большое число, но отрицательное.
Чтобы вынуть 4 байта, каждый бит 8 бит, они маскируются и сдвигаются вправо. Где 0xFF - FF в основании 16, 255 в основании 10, 0b11111111 или 11111111 в основании 2.
Существует бит операция и ( "и" ), которая на самом деле является умножением (по модулю 2).
x y x&y x|y
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1
Теперь, имея несколько бит abcdefgh
, и вы хотите проверить только биты def
, вы бы сделали:
abcdefgh & 00011100 = 000def00 = def00 (00011100 is called a mask)
(abcdefgh & 00011100) >> 2 = def (shift right 2)
Мы показываем вам два примера смены битов и "0xff" для преобразования десятичного числа обратно в IP-адрес. Смещение битов очень сложно объяснить словами, лучше рассмотреть бинарные потоки ниже:
//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();
}
для получения дополнительной информации, пожалуйста, проверьте Ссылка Ссылка 2
int
32-битный = 4 байта. Теперь, если эти байты не подписаны (как они есть, так как я никогда не видел отрицательный IP в своей жизни), они получают значения от 0 до 255. Правильно? Моя проблема - побитовые операции. Я тоже не понимаю концепции маскировки.