布隆过滤器(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实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2016-12-09

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 Web Filter 过滤器学习教程(推荐)

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

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 过滤器详细介绍及实例代码

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

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

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

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

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

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

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

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

JavaWeb之Filter过滤器详解

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

浅谈Java中的Filter过滤器

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

浅谈Java中ABA问题及避免

本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下. 在<Java并发实战>一书的第15章中有一个用原子变量实现的并发栈,代码如下: public class Node { public final String item; public Node next; public Node(String item){ this.item = item; } } public class ConcurrentStack { AtomicReference<Node> top

浅谈Java中Unicode的编码和实现

Unicode的编码和实现 大概来说,Unicode编码系统可分为编码方式和实现方式两个层次. 编码方式 字符是抽象的最小文本单位.它没有固定的形状(可能是一个字形),而且没有值."A"是一个字符,"€"也是一个字符.字符集是字符的集合.编码字符集是一个字符集,它为每一个字符分配一个唯一数字. Unicode 最初设计是作为一种固定宽度的 16 位字符编码.也就是每个字符占用2个字节.这样理论上一共最多可以表示216(即65536)个字符.上述16位统一码字符构成基

浅谈java中null是什么,以及使用中要注意的事项

1.null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型,例如: Integer i=null; Float f=null; String s=null; 但是不能把null赋值给基本类型,如int ,float,double等 int k=null ----------编译器会报错cannot convert from null to int 2.null是关键字,像public.static.final.它是大小写敏感的,你不能将

浅谈java中math类中三种取整函数的区别

math类中三大取整函数 1.ceil 2.floor 3.round 其实三种取整函数挺简单的.只要记住三个函数名翻译过来的汉语便能轻松理解三大函数,下面一一介绍 1.ceil,意思是天花板,java中叫做向上取整,大于等于该数字的最接近的整数 例: math.ceil(13.2)=14 math.ceil(-13.2)=-13 2.floor,意思是地板,java中叫做向下取整,小于等于该数字的最接近的整数 例: math.floor(13.2)=13 math.floor(-13.2)=-

浅谈Java中Collection和Collections的区别

1.java.util.Collection 是一个集合接口.它提供了对集合对象进行基本操作的通用接口方法.Collection接口在Java 类库中有很多具体的实现.Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式. Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set 2.java.util.Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,就像一

浅谈Java中注解Annotation的定义、使用、解析

此例子,用于说明如何在Java中对"注解 Annotation"的定义.使用和解析的操作.注解一般用于自定义开发框架中,至于为什么使用,此处不作过多说明,这里只说明如何使用,以作备记.下面例子已测试,可以正常运行通过. 1.注解自定义. 这里定义两个注解,分别用来注解类和注解属性. package cc.rulian.ann; import java.lang.annotation.ElementType; import java.lang.annotation.Retention;

浅谈java中的TreeMap 排序与TreeSet 排序

TreeMap: package com; import java.util.Comparator; import java.util.TreeMap; public class Test5 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TreeMap<String, String> tree = new TreeMap<String,

浅谈java中对集合对象list的几种循环访问

java中对集合对象list的几种循环访问的总结如下  1 经典的for循环 public static void main(String[] args) { List<String> list = new ArrayList(); list.add("123"); list.add("java"); list.add("j2ee"); System.out.println("=========经典的for循环=======

浅谈java中的一维数组、二维数组、三维数组、多维数组

这个数组可以看做新手学习,从一维数组 到 多维 数组 循环渐进,其实看起也很简单,一看便知,众所周知,一维.二维或许经常用到,用到二维以上应该就很少了. public class test { public static void main(String[] args) { /*一维数组*/ int num[] = {0,1,2}; /*下面输出 3 行数据,0 ~ 2*/ for (int i = 0; i < num.length; i++) { System.out.println("