示例:
// using Integer.parseInt
int i = Integer.parseInt("123");
你怎样才能做到相同的效果?
// using Integer.parseInt
int i = Integer.parseInt("123.45.55.34");
示例:
// using Integer.parseInt
int i = Integer.parseInt("123");
你怎样才能做到相同的效果?
// using Integer.parseInt
int i = Integer.parseInt("123.45.55.34");
你可能想要这样做:
// Parse IP parts into an int array
int[] ip = new int[4];
String[] parts = "123.45.55.34".split("\\.");
for (int i = 0; i < 4; i++) {
ip[i] = Integer.parseInt(parts[i]);
}
或者这样:
// Add the above IP parts into an int number representing your IP
// in a 32-bit binary form
long ipNumbers = 0;
for (int i = 0; i < 4; i++) {
ipNumbers += ip[i] << (24 - (8 * i));
}
当然,正如其他人建议的,使用InetAddress
可能比自己编写更合适...
long
,否则你将会溢出 int
并且对于任何大于 127.255.255.255
的 IP 地址得到错误的值。;-) - Aaron Blenkush对于IPv4地址,您可以这样做,因为部分只是整数版本的四个字节。
要将InetAddress转换为其整数表示,请执行以下操作:
int result = 0;
for (byte b: inetAdress.getAddress())
{
result = result << 8 | (b & 0xFF);
}
请注意,现在不应该使用32位整数来表示IP地址,因为我们正在进入IPV6地址的时代。
编辑:要在Java中将类似于“123.45.55.34”这样的字符串解析为有用的内容,可以使用InetAddress.getByName(yourString)
。
IPAddress Java库以多态方式支持IPv4和IPv6。免责声明:我是该库的项目经理。
下面的代码适用于IPv4和IPv6地址。使用您的IPv4地址示例:
IPAddress addr = new IPAddressString("123.45.55.34").getAddress();
BigInteger value = addr.getValue(); // 2066560802
if(addr.isIPv4()) {
int val = addr.toIPv4().intValue(); // 2066560802
}
您需要意识到,形式为123.45.55.34的IPv4地址实际上是代表地址的每个字节的4个三位数字。一次解析整个字符串不起作用。
其他人提到使用InetAddress
,但如果您只有IP的字符串表示形式,则据我所知无法轻松地实例化InetAddress
。
您可以执行以下操作:
public static int parseIp(String address) {
int result = 0;
// iterate over each octet
for(String part : address.split(Pattern.quote("."))) {
// shift the previously parsed bits over by 1 byte
result = result << 8;
// set the low order bits to the current octet
result |= Integer.parseInt(part);
}
return result;
}
192.168.0.1
这样的吗?;-) - Lukas EderSystem.out.println(
ByteBuffer.allocate(Integer.BYTES)
.put(InetAddress.getByName("0.0.1.0").getAddress())
.getInt(0));
输出:
256
抱歉重新打开一个旧问题,但对我来说似乎缺少一个可能的有效和高效的解决方案:
static int ipV4ToInt(int a1, int a2, int a3, int a4){
return (a1 << 24) ^ (a2 << 16) ^ (a3 << 8) ^ a4;
}
class MyAwesomeIPv4Utils {
private MyAwesomeIPv4Utils(){} // It's a library, sorry OOP addicted...
static int validateIpPart(int n){
if (n < 0 || n > 255)
throw new IllegalArgumentException("Invalid IP v4 part: " + n);
return n;
}
static int validateIpPart(String p){
return validateIpPart(Integer.parseInt(p));
}
static int internalIpV4ToInt(int a1, int a2, int a3, int a4){
// let validation outside, just for performance reasons (e.g. inlining and lazy evaluation): it can be made by the caller
return (a1 << 24) ^ (a2 << 16) ^ (a3 << 8) ^ a4;
}
// this can be made public as it handles the validation, and can be used to directly create int when you know the addresses at comple time
public static int ipV4ToInt(int a1, int a2, int a3, int a4){
return internalIpV4ToInt(
validateIpPart(a1),
validateIpPart(a2),
validateIpPart(a3),
validateIpPart(a4)
);
}
// this can be exposed too, as it handles both validation and parsing
public static int ipV4ToInt(String ipStr){
Objects.requireNonNull(ipStr, "null IP Address");
// If you prefer you can make this Pattern a static variable, to create it just once and shared (Patterns are thread-safe), but be careful with it's instantiation as it can be null at the first invokation of this static method
final Pattern ipPattern = Pattern.compile("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})");
final Matcher m = ipPattern.matcher(ipStr);
if (!m.matches())
throw new IllegalArgumentException("Invalid IP v4 address: " + ipStr);
return internalIpV4ToInt(
validateIpPart(m.group(1)),
validateIpPart(m.group(2)),
validateIpPart(m.group(3)),
validateIpPart(m.group(4))
);
}
}
IPAddressUtil#textToNumericFormatV4
的性能要优于 String#split
来获取IP地址的字节,此外它还会检查IP地址是否有效。
public int intOfIpV4(String ip) {
int result = 0;
byte[] bytes = IPAddressUtil.textToNumericFormatV4(ip);
if (bytes == null) {
return result;
}
for (byte b : bytes) {
result = result << 8 | (b & 0xFF);
}
return result;
}