Java转换IP+;从左到右
我正在尝试在长内存中存储IP地址和端口。下面的代码适用于值小于255的端口,但不适用于其他端口Java转换IP+;从左到右,java,bit-manipulation,Java,Bit Manipulation,我正在尝试在长内存中存储IP地址和端口。下面的代码适用于值小于255的端口,但不适用于其他端口 import java.util.*; import java.lang.*; import java.io.*; class Test { public static void main(String[] args) { String first = "192.168.1.2:84"; String second = "255.255.255.255:65
import java.util.*;
import java.lang.*;
import java.io.*;
class Test {
public static void main(String[] args) {
String first = "192.168.1.2:84";
String second = "255.255.255.255:65535";
long ip1 = ipToLong(first);
System.out.println("iptoLong : " + ip1);
System.out.println("longToIp : " + longToIp(ip1));
System.out.println();
ip1 = ipToLong(second);
System.out.println("iptoLong : " + ip1);
System.out.println("longToIp : " + longToIp(ip1));
}
public static long ipToLong(String ipAddress) {
int port = Integer.parseInt(ipAddress.substring(ipAddress.indexOf(":") + 1, ipAddress.length()));
ipAddress = ipAddress.replace(":", "").replace(""+port, "");
String[] ip = ipAddress.split("\\.");
long result = 0;
result |= Long.parseLong(ip[0]) << 40;
result |= Long.parseLong(ip[1]) << 32;
result |= Long.parseLong(ip[2]) << 24;
result |= Long.parseLong(ip[3]) << 16;
result |= port << 8;
result |= port;
return result;
}
public static String longToIp(long i) {
long port = ((i >> 8) & 0xFF) | (i & 0xFF);
return ((i >> 40) & 0xFF) +
"." + ((i >> 32) & 0xFF) +
"." + ((i >> 24) & 0xFF) +
"." + ((i >> 16) & 0xFF) +
":" + port;
}
}
正如您在第二个示例中看到的,它打印255而不是65535
以下是指向代码段的ideone链接:
谢谢 您对端口的编码和解码都是错误的 对于您正在进行的编码:
result |= port << 8;
result |= port;
long port = ((i >> 8) & 0xFF) | (i & 0xFF);
这(第一行)没有做一些有用的事情,将覆盖ip地址中的最低有效字节。但这并不是造成问题的原因——您需要使用不同的数字,如1.2.3.4:65534
,才能看到问题的实际效果
你应该做的是:
result |= 0xfeff00;
result |= 0x00feff;
result |= port & 0xFFFF;
(&0xFFFF
部分是为了保护您的代码不受负数和65535的影响,否则它们会覆盖IP)
要解码,您需要执行以下操作:
result |= port << 8;
result |= port;
long port = ((i >> 8) & 0xFF) | (i & 0xFF);
现在假设long
的最低16位包含0xFFFF
,那么您的代码会:
long port = ((0xFFFF >> 8) & 0xFF) | (0xFFF & 0xFF)
= 0xFF | 0xFF
= 0xFF;
相反,您期望的是0xFFFF
。改为:
long port = (i & 0xFFFF);
您对端口的编码和解码都是错误的 对于您正在进行的编码:
result |= port << 8;
result |= port;
long port = ((i >> 8) & 0xFF) | (i & 0xFF);
这(第一行)没有做一些有用的事情,将覆盖ip地址中的最低有效字节。但这并不是造成问题的原因——您需要使用不同的数字,如1.2.3.4:65534
,才能看到问题的实际效果
你应该做的是:
result |= 0xfeff00;
result |= 0x00feff;
result |= port & 0xFFFF;
(&0xFFFF
部分是为了保护您的代码不受负数和65535的影响,否则它们会覆盖IP)
要解码,您需要执行以下操作:
result |= port << 8;
result |= port;
long port = ((i >> 8) & 0xFF) | (i & 0xFF);
现在假设long
的最低16位包含0xFFFF
,那么您的代码会:
long port = ((0xFFFF >> 8) & 0xFF) | (0xFFF & 0xFF)
= 0xFF | 0xFF
= 0xFF;
相反,您期望的是0xFFFF
。改为:
long port = (i & 0xFFFF);
那是因为你把所有的东西都移位了8位。8位中可能的最大数字为255(=11111111)。如果你想存储一个大于255的数字,你必须移动超过8位。 255=11111111=8位,
65535=1111=16位。
这意味着您必须将所有内容再移动8位:
long result = 0;
result |= Long.parseLong(ip[0]) << 48;
result |= Long.parseLong(ip[1]) << 40;
result |= Long.parseLong(ip[2]) << 32;
result |= Long.parseLong(ip[3]) << 24;
result |= port << 16;
当您还可以选择执行以下操作时:
String[] ipadressandport = ipAddress.split(":");
int port = Integer.parseInt(ipaddressandport[1]);
String[] ip = ipaddressandport[0].split("\\.");
它看起来更干净,速度也更快。这是因为你把所有的东西都移位了8位。8位中可能的最大数字为255(=11111111)。如果你想存储一个大于255的数字,你必须移动超过8位。 255=11111111=8位,
65535=1111=16位。
这意味着您必须将所有内容再移动8位:
long result = 0;
result |= Long.parseLong(ip[0]) << 48;
result |= Long.parseLong(ip[1]) << 40;
result |= Long.parseLong(ip[2]) << 32;
result |= Long.parseLong(ip[3]) << 24;
result |= port << 16;
当您还可以选择执行以下操作时:
String[] ipadressandport = ipAddress.split(":");
int port = Integer.parseInt(ipaddressandport[1]);
String[] ip = ipaddressandport[0].split("\\.");
它看起来更干净,速度也更快