杰瑞科技汇

Java IP地址如何转Long?

Of course! Converting an IP address to a long in Java is a common task, primarily for efficient storage and comparison. The process is called an "IP address to integer" or "IP to long" conversion, and it's based on treating the IP address as a single 32-bit number.

Java IP地址如何转Long?-图1
(图片来源网络,侵删)

Here’s a complete guide covering the concept, manual implementation, and the modern, recommended approach using Java's built-in libraries.

The Core Concept: Dotted-Quad Notation

An IPv4 address like 168.1.1 is just a human-readable way to write a 32-bit binary number. Each of the four numbers (octets) represents 8 bits.

  • 192 -> 11000000
  • 168 -> 10101000
  • 1 -> 00000001
  • 1 -> 00000001

When you combine them, you get the full 32-bit number: 11000000 10101000 00000001 00000001

This single binary number can be stored in a 32-bit int or a 64-bit long in Java. The conversion process involves calculating this number from the four octets.

Java IP地址如何转Long?-图2
(图片来源网络,侵删)

Method 1: The Manual "From Scratch" Approach

This method is great for understanding the underlying logic. The key is to use bit-shifting and the bitwise OR operator.

The formula is: long ipLong = (firstOctet << 24) | (secondOctet << 16) | (thirdOctet << 8) | (fourthOctet);

Code Example

public class IpConverter {
    /**
     * Converts an IP address string in dotted-quad format to a long.
     *
     * @param ipAddress The IP address string (e.g., "192.168.1.1").
     * @return The long representation of the IP address.
     * @throws NumberFormatException if the IP address is invalid.
     */
    public static long ipToLong(String ipAddress) {
        // Split the IP string into its four octets
        String[] octets = ipAddress.split("\\.");
        // An IP address must have exactly 4 parts
        if (octets.length != 4) {
            throw new IllegalArgumentException("Invalid IP address format: " + ipAddress);
        }
        long result = 0;
        for (int i = 0; i < 4; i++) {
            // Convert the octet string to an integer
            int octet = Integer.parseInt(octets[i]);
            // Validate that the octet is in the valid range (0-255)
            if (octet < 0 || octet > 255) {
                throw new IllegalArgumentException("Invalid octet in IP address: " + octet);
            }
            // Shift the bits of the octet to the correct position and OR it with the result
            // The left shift amount is (3 - i) * 8, which is equivalent to 24, 16, 8, 0
            result |= (long) octet << (3 - i) * 8;
        }
        return result;
    }
    public static void main(String[] args) {
        String ip = "192.168.1.1";
        long ipLong = ipToLong(ip);
        System.out.println("IP Address: " + ip);
        System.out.println("Long Value: " + ipLong); // Output: 3232235777
        // You can verify this in any programming language or online calculator
        // 192 * 256^3 + 168 * 256^2 + 1 * 256^1 + 1 * 256^0 = 3232235777
    }
}

Explanation:

  1. ipAddress.split("\\."): Splits the string by the character. We need to escape the because it's a special regex character.
  2. Integer.parseInt(octets[i]): Converts each string part (e.g., "192") into an integer.
  3. *`long octet << (3 - i) 8`**: This is the core of the conversion.
    • << is the left shift operator. It moves the bits of a number to the left, filling the empty spaces with zeros.
    • The first octet (192) is shifted left by 24 bits (<< 24).
    • The second octet (168) is shifted left by 16 bits (<< 16).
    • The third octet (1) is shifted left by 8 bits (<< 8).
    • The fourth octet (1) is not shifted (<< 0).
  4. : The bitwise OR operator. It combines the shifted values into a single long. Since the octets are shifted into non-overlapping bit positions, OR-ing them simply "glues" them together.

Method 2: The Modern & Recommended Approach (Java 1.5+)

Java's standard library provides built-in methods to handle this conversion cleanly and reliably. This is the best approach for production code as it's less error-prone and more readable.

Java IP地址如何转Long?-图3
(图片来源网络,侵删)

The key class is java.net.InetAddress.

Code Example

import java.net.InetAddress;
import java.net.UnknownHostException;
public class IpConverterModern {
    /**
     * Converts an IP address string to a long using Java's built-in InetAddress.
     *
     * @param ipAddress The IP address string (e.g., "192.168.1.1").
     * @return The long representation of the IP address.
     * @throws UnknownHostException if the IP address is invalid or cannot be resolved.
     */
    public static long ipToLong(String ipAddress) throws UnknownHostException {
        // 1. Get an InetAddress object from the string
        InetAddress inetAddress = InetAddress.getByName(ipAddress);
        // 2. Get the address as a byte array (it will be 4 bytes for IPv4)
        byte[] bytes = inetAddress.getAddress();
        // 3. Convert the byte array to a long
        // The bytes are in network order (big-endian), so we can directly convert them.
        long result = 0;
        for (byte b : bytes) {
            // & 0xFF is crucial to avoid sign extension when converting a byte to a long
            result = result << 8 | (b & 0xFF);
        }
        return result;
    }
    // A more concise version of the same logic
    public static long ipToLongConcise(String ipAddress) throws UnknownHostException {
        byte[] bytes = InetAddress.getByName(ipAddress).getAddress();
        return ((bytes[0] & 0xFFL) << 24) | ((bytes[1] & 0xFFL) << 16) |
               ((bytes[2] & 0xFFL) << 8)  | (bytes[3] & 0xFFL);
    }
    public static void main(String[] args) throws UnknownHostException {
        String ip = "192.168.1.1";
        long ipLong = ipToLong(ip);
        System.out.println("IP Address: " + ip);
        System.out.println("Long Value: " + ipLong); // Output: 3232235777
        // You can also convert back
        String originalIp = InetAddress.getByAddress(new byte[]{
            (byte) (ipLong >> 24),
            (byte) (ipLong >> 16),
            (byte) (ipLong >> 8),
            (byte) (ipLong)
        }).getHostAddress();
        System.out.println("Converted Back to IP: " + originalIp); // Output: 192.168.1.1
    }
}

Explanation:

  1. InetAddress.getByName(ipAddress): This static factory method takes a string and returns an InetAddress object. It performs validation for you, throwing an UnknownHostException if the format is wrong.
  2. inetAddress.getAddress(): This method returns the IP address as a byte array. For an IPv4 address like 168.1.1, this will be a 4-element byte array: [-64, -88, 1, 1]. Notice that Java uses two's complement for negative numbers, so 192 becomes -64.
  3. (b & 0xFF): This is a critical step. When you cast a byte to anything larger (like an int or long), Java performs "sign extension." This means if the most significant bit of the byte is 1 (as it is for 192 which is 11000000), it fills the higher bits with 1s, leading to a negative number. By masking with 0xFF (which is 00000000 00000000 00000000 11111111), we clear all but the last 8 bits, ensuring we get the correct unsigned value (e.g., -64 & 0xFF becomes 192).
  4. result = result << 8 | (b & 0xFF): This loop builds the long value byte by byte, starting from the first byte of the array (which is the most significant part of the address).

Bonus: Converting Long back to IP Address

It's useful to have the reverse function.

public static long ipToLong(String ipAddress) throws UnknownHostException {
    return bytesToLong(InetAddress.getByName(ipAddress).getAddress());
}
public static String longToIp(long ipLong) {
    // Use an array of bytes to build the IP string
    return String.format("%d.%d.%d.%d",
        (ipLong >> 24) & 0xFF,
        (ipLong >> 16) & 0xFF,
        (ipLong >> 8)  & 0xFF,
        ipLong & 0xFF);
}
public static void main(String[] args) {
    long ipLong = 3232235777L;
    String ipAddress = longToIp(ipLong);
    System.out.println("Long: " + ipLong + " -> IP: " + ipAddress); // 192.168.1.1
}

Summary: Which Method to Use?

Feature Manual Method InetAddress Method
Dependencies None java.net (standard library)
Readability Good, but requires understanding bitwise ops. Excellent, intent is very clear.
Robustness You must write validation logic yourself. Built-in validation (UnknownHostException).
Best For Learning the concept, environments without network access. All production applications. It's the standard, safe, and recommended way.
分享:
扫描分享到社交APP
上一篇
下一篇