本文共 2542 字,大约阅读时间需要 8 分钟。
常用的ip地址是遵循IPv4协议,由32位的二进制数组成,在具体设置时看到的是4个0~255之间的数组成,常见就有本地环回地址“127.0.0.1”,还有常用的局域网地址“192.168.0.1”之类的。所以IPv4的地址能表示的范围就2的31次幂到2的0次幂之间。
要理解10进制数在计算机内存中也是以0或1的方式去表示的,同时移位运算相比其他的四则运算对于计算机来说,运算效率更高。所以只需要定义一个范围大于或等于2的31次幂的整数类型,来进行位运算即可。在java中,int型只有4个字节,长度不够,所以选择使用long型,long型有8个字节,除去符号位足以保存2的31次幂的数。
代码如下/** * 将4位的ip地址数组转二进制对应的十进制数. * @param ipArr 4位的ip地址int数组. * @return ip地址数组转二进制对应的十进制数. */ private static long getIpByteToTen(int[] ipArr){ //定义临时值 long temp = 0; //迭代数组 for(int i : ipArr ){ //左移8位后,加上当前数值 temp =(temp << 8) + i; } return temp; }
用int型的数组保存切割好的ip地址,然后迭代整个数组,首个数字进入循环,"<<"(符号位保持不动的左移位运算),左移8位后加上首个数字。继续迭代,再左移8位在加上当前第二个数字,依次迭代完整个数组。此时内存中保存的temp值就是真实ip地址的数值。
代码如下
/** * IP地址运算判断是否在分配的地址范围内. * @param enterIp 起始ip地址. * @param endIp 结束ip地址. * @param nowIp 当前ip地址. * @return 运算结果 true :当前地址在范围内 false:当前地址不在范围内. * @throws IpAddrFormatException ip地址转化异常。 */ public static boolean isSecurityIpAddr(String enterIp,String endIp,String nowIp) throws IpAddrFormatException { //传入的ip地址字符串,切成数组 String [] enterIpArry = enterIp.split("\\."); String [] endIpArry = endIp.split("\\."); String [] nowIpArry = nowIp.split("\\."); //初始化接受转化数字的数组 int [] enterIpNumArry = new int[4]; int [] endIpNumArry = new int[4]; int [] nowIpNumArry = new int[4]; //判断数组格式是否正确 if(enterIpArry.length==4&&endIpArry.length==4){ try { //迭代起始ip地址数组,将String转成int for(int i=0 ; i < 4; i++){ enterIpNumArry[i] = Integer.parseInt(enterIpArry[i]); } //迭代结束ip地址数组,将String转成int for(int i=0 ; i < 4; i++){ endIpNumArry[i] = Integer.parseInt(endIpArry[i]); } //迭代当前ip地址数组,将String转成int for(int i=0 ; i < 4; i++){ nowIpNumArry[i] = Integer.parseInt(nowIpArry[i]); } }catch (NumberFormatException ex){ //捕获数值转化异常 //抛出自定义异常 throw new IpAddrFormatException( ex.getCause()); } }else { //抛出自定义异常 throw new IpAddrFormatException("ipAddr format is not true"); } //定义long型获取ip地址的二进制转十进制数 long enterIpTenNum = getIpByteToTen(enterIpNumArry); long endIpTenNum = getIpByteToTen(endIpNumArry); long nowIpTenNum = getIpByteToTen(nowIpNumArry); //判断当前ip数值是否在范围内 if(nowIpTenNum >= enterIpTenNum && nowIpTenNum <= endIpTenNum){ return true; } return false; }
现在已经把实现方法封装到工具方法中。
测试代码如下@Test public void contextLoads() throws IpAddrFormatException { boolean isSecurity = IPAddrUtil.isSecurityIpAddr("192.168.0.10","192.168.0.55","192.168.0.20"); }
希望有有缘人可以看到,很简单,也很好用。
转载地址:http://mqugn.baihongyu.com/