算法题:实现一个IP白名单过滤器
最近看到一则招聘的JD,附了一个算法题的链接,原题如下:
请实现一个IP白名单过滤算法,实现以下接口
boolean addWhiteIpAddress(String ip);
boolean isWhiteIpAddress(String ip);
要求如下:
占用空间尽量少
运算效率尽量高
在内存中完成查询及判断
接口可能被并发询问
尽量能存储整个IP地址空间
代码可运行,且包含单测
思路:
如题,需要实现的是一个白名单的功能而不是黑名单,且要求尽可能存储整个IP地址空间,所以如果直接存储ip地址的字符串32位JVM下需要约:2^32 * (32+32+ (7+15)/2) = 300GB(这里只是非常粗略的估算),当然如果把字符串换成char数组可以省下对象头和类型指针,预计需约44GB,这完全超出了32位JVM的堆空间,而且就算借助于文件系统和硬盘,这么大数据量的字符串比较效率也是非常低下的。
所以换个思路,针对IPV4,一个IP地址为32个bit位,可以直接将IP地址转换为int类型。又因为白名单只有两种状态,要么在白名单中,要么不在,所以很自然就想到位图了,用两个BitSet即可存储全部IPV4的地址,占用512M多的内存,也支持随机访问。缺点:
- volatile修饰,性能会降低(修饰对象或数组,如果对象属性或数组元素被修改,可以间接保证对象属性或数组元素的线程可见性)
- 目前没考虑IPV6
- 测试的数据量不够,可能有些边界还没考虑到,还没做性能测试
import java.util.BitSet;
import org.junit.Test;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
public class IPFiliterTest {
// Java语言中没有无符号整形,int的最大值只能表示到0x7fffffff,所以需要两个BitSet来存储高低位
private static volatile BitSet low = new BitSet(Integer.MAX_VALUE);
private static volatile BitSet high = new BitSet(Integer.MAX_VALUE);
/**
* 固定8位,前面不足的补零
* @param num
* @return
*/
private static String getByteBinaryStr(int num) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 8; i++) {
if ((num & 1) == 1) {
sb.append(1);
} else {
sb.append(0);
}
num = num >> 1;
}
return sb.reverse().toString();
}
/**
* 将IP地址字符串转换为int
* @param ip
* @return
*/
private static int chgIpStrToInt(String ip) {
if (ip == null || StringUtils.isEmpty(ip)) {
throw new RuntimeException("Null string");
}
String[] arr = ip.split("\\.");
if (arr == null || arr.length != 4) {
throw new RuntimeException("Invalid ip");
}
if ("128.0.0.0".equals(ip)) {
return Integer.MIN_VALUE;
}
StringBuilder sb = new StringBuilder();
sb.append(getByteBinaryStr(new Integer(arr[0])));
sb.append(getByteBinaryStr(new Integer(arr[1])));
sb.append(getByteBinaryStr(new Integer(arr[2])));
sb.append(getByteBinaryStr(new Integer(arr[3])));
String intStr = sb.toString();
// Integer.valueOf处理负数会有问题
if (intStr.charAt(0) == '1') {
char[] chars = intStr.toCharArray();
chars[0] = '0';
intStr = new String(chars);
return 0 - Integer.valueOf(intStr, 2).intValue();
}
return Integer.valueOf(intStr, 2).intValue();
}
public static boolean addWhiteIpAddress(String ip){
int ipInt = chgIpStrToInt(ip);
if (ipInt < 0) {
high.set(ipInt+Integer.MAX_VALUE+1);
} else {
low.set(ipInt);
}
return true;
}
public static boolean isWhiteIpAddress(String ip) {
int ipInt = chgIpStrToInt(ip);
if (ipInt < 0) {
return high.get(ipInt+Integer.MAX_VALUE+1);
} else {
return low.get(ipInt);
}
}
@Test
public void test() throws InterruptedException {
String ip1= "0.0.0.0";
addWhiteIpAddress(ip1);
Assert.isTrue(isWhiteIpAddress(ip1));
String ip2= "127.0.0.1";
addWhiteIpAddress(ip2);
Assert.isTrue(isWhiteIpAddress(ip2));
String ip3= "255.255.255.255";
addWhiteIpAddress(ip3);
Assert.isTrue(isWhiteIpAddress(ip3));
String ip4= "128.0.0.0";
addWhiteIpAddress(ip4);
Assert.isTrue(isWhiteIpAddress(ip4));
Assert.isTrue(!isWhiteIpAddress("0.0.0.1"));
Assert.isTrue(!isWhiteIpAddress("1.1.1.1"));
Assert.isTrue(!isWhiteIpAddress("001.001.001.001"));
}
}
算法题:实现一个IP白名单过滤器的更多相关文章
- 如何为ASP.NET Core设置客户端IP白名单验证
原文链接:Client IP safelist for ASP.NET Core 作者:Damien Bowden and Tom Dykstra 译者:Lamond Lu 本篇博文中展示了如何在AS ...
- Windows Azure Web Site (14) Azure Web Site IP白名单
<Windows Azure Platform 系列文章目录> 我们知道,在Azure Cloud Service和Virtual Machine,可以通过Endpoint ACL (Ac ...
- IP白名单的实现(PHP)
有些项目可能会用到一个IP地址的白名单黑名单之类的验证. 比如,只有IP地址在白名单中,才可以访问该系统. 那么此时,白名单的维护,一般是一个文件,里边是一些IP地址(每行一个IP),当然也有的可能是 ...
- 对actuator的管理端点进行ip白名单限制(springBoot添加filter)
在我们的SpringCloud应用中,我们会引入actuator来进行管理和监控我们的应用 常见的有:http://www.cnblogs.com/yangzhilong/p/8378152.html ...
- Java IP白名单相关工具类
关于设置IP白名单相关的一些方法,整理,记录了一下. package com.tools.iptool; import java.util.ArrayList; import java.util.Ha ...
- Data Lake Analytics IP白名单设置攻略
当我们成功开通了 DLA 服务之后,第一个最想要做的事情就是登录 DLA 数据库.而登录数据库就需要一个连接串.下面这个页面是我们首次开通 DLA 之后的界面,在这里我们要创建一个服务访问点. 在上面 ...
- 嵌入式Linux可用的防火墙——iptables:实现ip白名单、mac地址白名单
iptables是linux系统下的一个功能强大的模块,不仅可以用作防火墙,还可以实现NAT等众多路由功能.iptables的容器有很清晰的层次关系: 1. iptables是表的容器,iptable ...
- 利用CentOS系统IPtables防火墙添加网站IP白名单
参考博文: 利用CentOS系统IPtables防火墙添加360网站卫士节点IP白名单 centos6.5添加白名单如下: 在防火墙 配置文件中加入白名单 ip -A INPUT -s 183.13 ...
- 解决微信公众平台IP白名单
微信公众平台,作为自媒体的旗舰级产品,越来越多的人已经投入它的怀抱.正如它的广告词所说:再小的个体,也有品牌 好吧,闲话不多说,今天要说的是它的IP白名单机制. 我们现在安装的大部分的电信的家庭级别的 ...
随机推荐
- WebGL three.js学习笔记 使用粒子系统模拟时空隧道(虫洞)
WebGL three.js学习笔记 使用粒子系统模拟时空隧道 本例的运行结果如图: 时空隧道demo演示 Demo地址:https://nsytsqdtn.github.io/demo/sprite ...
- Hugo + Github Pages 搭建个人博客
尝试过 Hexo .GatsbyJs. Vuepress 搭建博客后,对这些工具最大的不满,就是运行速度以及打包速度. 后来看到 Hugo ,号称最快的静态站点生成器后. 尝试搭建博客,发现不管是运行 ...
- jdk源码阅读笔记-LinkedList
一.LinkedList概述 LinkedList的底层数据结构为双向链表结构,与ArrayList相同的是LinkedList也可以存储相同或null的元素.相对于ArrayList来说,Linke ...
- 为什么我的会话状态在ASP.NET Core中不工作了?
原文:Why isn't my session state working in ASP.NET Core? Session state, GDPR, and non-essential cookie ...
- Android根据word模板文档将表单数据生成word文档的方案整理
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 尝试的方案包括以下几种: freemarker 只能在java项目上运行,无法在Android项目上运行: 参考资料:<Fre ...
- 『备注』GDI+ 绘制文本有锯齿,透明背景文本绘制
背景: GDI+ 绘制文本 时,如果 背景是透明的 —— 则会出现 锯齿. //其实,我不用这三个 属性 好多年了 //而且,这三个属性 在关键时刻还有可能 帮倒忙 //关键是:这三个属性,鸟用都没有 ...
- asp.net mvc 三层加EF两表联查
首先打开vs软件新建项目创建web中的mvc项目再右击解决方案创建类库项目分别创建DAL层和BLL层再把DAL层和BLL层的类重命名在mvc项目中的Models文件夹创建model类在DAL创建ADO ...
- 让 .NET 更方便的导入导出 Excel
让 .Net 更方便的导入导出Excel Intro 因为前一段时间需要处理一些 excel 数据,主要是导入/导出操作,将 Excel 数据转化为对象再用程序进行处理和分析,没有找到比较满意的库,于 ...
- 2.JAVA-基础语法以及String的介绍
1.goto和const 目前java中,和C/C++有点区别,就是暂未用到goto const关键字.示例如下: public class Hello{ public static void mai ...
- 设计模式之创建类模式PK
创建类模式包括: 工厂方法模式 建造者模式 抽象工厂模式 单例模式 原型模式 创建类模式能够提供对象的创建和管理职责. 其中单例模式和原型模式非常容易理解, 单例模式是要保持在内存中只有一个对象,原型 ...