布隆过滤器(Bloom Filter)的Java实现方法

布隆过滤器原理很简单:就是把一个字符串哈希成一个整数key,然后选取一个很长的比特序列,开始都是0,在key把此位置的0变为1;下次进来一个字符串,哈希之后的值key,如果在此比特位上的值也是1,那么就说明这个字符串存在了。

如果按照上面的做法,那就和哈希算法没有什么区别了,哈希算法还有重复的呢。

布隆过滤器是将一个字符串哈希成多个key,我还是按照书上的说吧。

先建立一个16亿二进制常量,然后将这16亿个二进制位全部置0。对于每个字符串,用8个不同的随机产生器(F1,F2,.....,F8)产生8个信息指纹(f1,f2,....,f8).再用一个随机数产生器G把这八个信息指纹映射到1到16亿中的8个自然数g1,g2,...,g8。现在把这8个位置的二进制位全部变为1。这样一个布隆过滤器就建好了。

那么如何检测一个字符串是否已经存在了呢?

现在用8个随机数产生器(F1,F2,...,F8)对这个字符串产生8个信息指纹s1,s2,...,s8,然后将这8个信息指纹对应到布隆过滤器的8个二进制位,分别是T1,T2,...,T8.如果字符串存在,那么显然T1,T2,...,T8对应的二进制位都应该是1。就是这样来判断字符串是否已经存在的。

其实布隆过滤器就是对哈希算法的一个扩展,既然本质是哈希,那么就肯定会有不足,也就是说,肯定会有误判,一个字符串明明没有出现过而布隆过滤器判断出现了,虽然可能性很小,但是确实存在。

那么如何减少这种概率呢,首先可以想到的是如果将8个信息指纹扩展到16个错误的概率肯定会降低,但是也要考虑到,这样的话,那么一个布隆过滤器所能存储的字符串数量也降低了1倍;另外就是选取很好的哈希函数,对字符串的哈希方法有很多种,其中不乏很好的哈希函数。

布隆过滤器主要运用在过滤恶意网址用的,将所有的恶意网址建立在一个布隆过滤器上,然后对用户的访问的网址进行检测,如果在恶意网址中那么就通知用户。这样的话,我们还可以对一些常出现判断错误的网址设定一个白名单,然后对出现判断存在的网址再和白名单中的网址进行匹配,如果在白名单中,那么就放行。当然这个白名单不能太大,也不会太大,布隆过滤器错误的概率是很小的。有兴趣的读者可以去查阅,布隆过滤器的错误率。

下面给出Java版的布隆过滤器源码:

import java.util.BitSet; 

/**
 *
 * @author xkey
 */
public class BloomFilter { 

  private static final int DEFAULT_SIZE = 2 << 24;//布隆过滤器的比特长度
  private static final int[] seeds = {3,5,7, 11, 13, 31, 37, 61};//这里要选取质数,能很好的降低错误率
  private static BitSet bits = new BitSet(DEFAULT_SIZE);
  private static SimpleHash[] func = new SimpleHash[seeds.length]; 

  public static void addValue(String value)
  {
    for(SimpleHash f : func)//将字符串value哈希为8个或多个整数,然后在这些整数的bit上变为1
      bits.set(f.hash(value),true);
  } 

  public static void add(String value)
  {
    if(value != null) addValue(value);
  } 

  public static boolean contains(String value)
  {
    if(value == null) return false;
    boolean ret = true;
    for(SimpleHash f : func)//这里其实没必要全部跑完,只要一次ret==false那么就不包含这个字符串
      ret = ret && bits.get(f.hash(value));
    return ret;
  } 

  public static void main(String[] args) {
    String value = "www.jb51.net";
    for (int i = 0; i < seeds.length; i++) {
      func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
    }
    add(value);
    System.out.println(contains(value));
  }
} 

class SimpleHash {//这玩意相当于C++中的结构体 

  private int cap;
  private int seed; 

  public SimpleHash(int cap, int seed) {
    this.cap = cap;
    this.seed = seed;
  } 

  public int hash(String value) {//字符串哈希,选取好的哈希函数很重要
    int result = 0;
    int len = value.length();
    for (int i = 0; i < len; i++) {
      result = seed * result + value.charAt(i);
    }
    return (cap - 1) & result;
  }
} 

总结:布隆过滤器是对哈希算法的一种创新,而且需要消耗的空间也很小,错误率很低。总之这种创新的思路很值得学习,是一种对bit这种数据类型的运用。

以上这篇布隆过滤器(Bloom Filter)的Java实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • JAVAEE Filter 过滤器设置是否缓存实例详解

    在网页中,每次的客户端访问服务器,有部分不用重复请求,如有些图片,视频等就没有必要每次都请求,这样会让服务器增大工作量.为了防止这样,我们采用过滤器来设置客户端是都缓存. 页面的缓存与不缓存设置及html页面中meta的作用 HTTP1.1中启用Cache-Control 来控制页面的缓存与否,这里介绍几个常用的参数: no-cache,浏览器和缓存服务器都不应该缓存页面信息: public,浏览器和缓存服务器都可以缓存页面信息: no-store,请求和响应的信息都不应该被存储在对方的磁盘系统

  • javaweb中Filter(过滤器)的常见应用

    一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题 package me.gacl.web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException;

  • Java过滤器filter_动力节点Java学院整理

    Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器,非常简单,只要实现Servlet  API中的Filter接口即可,同时在该web应用[WEB-INF]目录下的web.xml文件中配置<filter>和<filter-mapping>两个标签.其中可以根据配置指定过滤的页面或者Servlet. 也就是说我们在web工程中光光写Filter过滤器的Java代码是不会起作用的,要在

  • java 过滤器filter防sql注入的实现代码

    实例如下: XSSFilter.java public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws IOException, ServletException { //flag = true 只做URL验证; flag = false 做所有字段的验证; boolean flag = true; if(flag){ //只

  • java 过滤器模式(Filter/Criteria Pattern)详细介绍

    java 过滤器模式(Filter/Criteria Pattern) 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准. 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以

  • java中Filter过滤器处理中文乱码的方法

    注意问题:在学习用selvert的过滤器filter处理中文乱码时,在filter配置初始化时用了utf-8处理中文乱码,而在提交的jsp页面中却用了gbk.虽然两种都可以出来中文乱码,但是却造成了处理乱码的格式不一致.所以编译出错. 解决方法:所有地方都用utf-8或gbk 复制代码 代码如下: //过滤器类CharactorFilter.jsppackage cn.com.Filter; import java.io.IOException; import javax.servlet.Fil

  • 浅谈Java中的Filter过滤器

    Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. 它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理.使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交

  • JavaWeb之Filter过滤器详解

    原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可以锻炼锻炼.言归正传,过滤器从字面理解她的话有拦网.过滤的功能,可以算是JavaWeb的拦精灵. 一.由来 客户端发起请求,那服务器不能什么请求都做出响应,做拦截处理,不仅能减轻服务器的压力,还能保护数据的安全,同样服务端做出响应给客户端时有时也需要进行过滤,比如我们常见的图片添加水印.为了处理这些问题,于是过滤器出现了.有时不仅仅对请求与响应进行一层的过滤

  • Java Web Filter 过滤器学习教程(推荐)

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter.通过F

  • Java Filter 过滤器详细介绍及实例代码

    Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. 它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后处理.使用Filter 的完整流程:Filter 对用户请求进行预处理,接着将

随机推荐