说明:转换仅支持ipv4地址
可实行性分析
ipv4 地址格式: [0-255].[0-255].[0-255].[0-255]
ipv4地址分为4段, 每一段是一个[0-255]
之间的数字,可见第一段可使用的数字个数为256=2^8
, 刚好是一个字节能表示的无符号整数范围。那4段就是4个字节。 也就是说只需要4个字节就能存下ip地址, java中一个int
是4个字节,一个int就能表示一个ipv4地址。
端口的范围是 0-65535
, 刚好是2^16
个数字, 是两个字节能表示的无符号整数范围。
所以实际上存储 ip:port
组合只需要6个字节, java中long
是8个字节, 完全能够表示ip:port
组合。
代码实现
实现依赖了guava
来处理整数和字节数组的转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency> import com.google.common.primitives.Bytes; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import sun.net.util.IPAddressUtil;
import java.util.Arrays;
/** * ip、ip:port 和 int、long的相互转换 * * @author huaxiaoer * @since 2020-06-17 */ public class IpAddressUtils {
/** * ip 转换成int型, 结果可能为负数, 如果要求正数,使用 ipToLong * @param ipv4 * @param port * @return */ public static int ipToInt(String ipv4){ byte[] address = IPAddressUtil.textToNumericFormatV4(ipv4); return Ints.fromByteArray(address); }
/** * ip 转换成long型 * @param ipv4 * @param port * @return */ public static long ipToLong(String ipv4){ return ipToInt(ipv4) & 0xFFFFFFFFL; }
/** * int 转换为ip * @param num */ public static String intToIp(int num){ byte[] bytes = Ints.toByteArray(num); return (bytes[0] & 0xff) + "." + (bytes[1] & 0xff) + "." + (bytes[2] & 0xff) + "." + (bytes[3] & 0xff); }
/** * int 转换为ip * @param num */ public static String longToIp(long num){ byte[] bytes = Longs.toByteArray(num); return (bytes[4] & 0xff) + "." + (bytes[5] & 0xff) + "." + (bytes[6] & 0xff) + "." + (bytes[7] & 0xff); }
/** * ip:port 组合转换成long型 * @param ipv4 * @param port * @return */ public static long ipPortToLong(String ipv4, int port){ byte[] address = IPAddressUtil.textToNumericFormatV4(ipv4); byte[] socket = Bytes.concat( Ints.toByteArray(port),address); return Longs.fromByteArray(socket); }
/** * long 转换为ip:port 字符串 * @param num */ public static String longToIpPortStr(long num){ Object[] ipPort = longToIpPort(num); return ipPort[0] + ":" + ipPort[1]; }
/** * long 转换为[ip,port]数组 * @param num * @return [ip,port] */ public static Object[] longToIpPort(long num){ byte[] bytes = Longs.toByteArray(num); byte[] portBytes = Arrays.copyOfRange(bytes, 0, 4); byte[] ipBytes = Arrays.copyOfRange(bytes, 4, 8); String ip = (ipBytes[0] & 0xff) + "." + (ipBytes[1] & 0xff) + "." + (ipBytes[2] & 0xff) + "." + (ipBytes[3] & 0xff); int port = Ints.fromByteArray(portBytes); return new Object[]{ip,port}; } }
|