如何在Java中将字符串(IP号码)转换为Integer



示例:

// 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可能比自己做事更合适。。。

您可以为IP V4地址执行此操作,因为这些部分只是整数版本的四个字节。

执行此操作可将InetAddress转换为其整数表示形式:

int result = 0;  
for (byte b: inetAdress.getAddress())  
{  
    result = result << 8 | (b & 0xFF);  
}

请注意,现在不应该使用32位整数作为IP地址,因为我们正进入IPV6地址时代

EDIT:要将类似"123.45.55.34"的字符串解析为java中有用的字符串,可以使用INetAddress.getByName(yourString)

您需要意识到,形式为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;
}

IPAddress Java库以多态方式支持IPv4和IPv6。免责声明:我是那个图书馆的项目经理。

以下代码适用于IPv4和IPv6地址。使用您的示例IPv4地址:

IPAddress addr = new IPAddressString("123.45.55.34").getAddress();
BigInteger value = addr.getValue(); // 2066560802

如果是IPv4,您可以直接使用int值:

if(addr.isIPv4()) {
    int val = addr.toIPv4().intValue(); // 2066560802
}
System.out.println(
        ByteBuffer.allocate(Integer.BYTES)
        .put(InetAddress.getByName("0.0.1.0").getAddress())
        .getInt(0));

输出:

256

我认为您可能误解了自己的问题。你想把它转换成一个int值吗?如果你这样做,那么你的问题的前提是错误的,因为IP号码不是一个数字,而是多个字节的值。它不是123456789000,而是字节123字节455字节789和字节000。我知道这些不是真正的字节数,但重点是这不是1230亿45600亿789000。在我看来,你把整个事情视为一个整数,而IP地址的情况并非如此。

很抱歉重新打开了一个旧的问题,但在我看来,它似乎缺少了一个可能有效且高效的解决方案:

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在获取ip字节方面比String#split表现更好,此外,它还检查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;
    }

最新更新