`
huangfeiNetJava
  • 浏览: 40799 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

字符串hash的研究

 
阅读更多

字符串哈希的研究

关于hash函数,其存在的理由就是让存入的数据得到好的立足之地(就像给存入的数据一个唯一的门牌号,我们就可以很容易的找到它所在地点),而且不让数据扎堆也是很重要的(而不是让数据扎堆,毕竟在一间几十上百号人的屋子找个人相对比较困难的)。

由此,hash函数应该,也必须要让数据“散开”,数据不必争房子住,如此冲突就少了,社会也就和谐了。

以下为hash设计历程:(一步一步、做足苦力啊!先贴代码,然后是自己的一点分析,再后是测试的统计数据)

设计1

private int FirstHash(String str){
        char[] chars = str.trim().toCharArray();
        int hash = 0;
        int count = 0;
        int length = chars.length;
        while (count < length) {
                   hash = (int) chars[count] + (hash << 8) + (hash << 16);
                   count++;
        }
        return hash & 0x7FFFFFFF;
}

 

设计2:

while (count < length) {
         hash = (int) chars[count] + (hash << 8) + (hash << 16) – hash;
         count++;
}

 

设计3:(只改动了一个数据哦!!!)

while (count < length) {
          hash = (int) chars[count] + (hash << 7) + (hash << 16) – hash;
          count++;
}

 

设计4

while (count < length) {
      hash = (int) chars[count] + (hash << 7) + (hash << 16) + (hash << 24) – hash;
      count++;
}

附:hashSethashMap的哈希函数(以便比较)

private int SystemHash(String s) {
      int hash = s.hashCode();
      hash ^= (hash >>> 20) ^ (hash >>> 12);
      return (hash ^ (hash >>> 7) ^ (hash >>> 4));
}

 

 

必须说明:现在只测试英文单词为存入的数据对象。

分析:

    刚开始想到设计1是根据字符的二进制编码的。Javachar型数据是2 byte。但想到超过ASCLL256char型数据没法手工输入(我试了一下,char型数据超过256的都打印个?),最常用的英文单词实际上就是char数组,每个字母必不超过256。说了这么多,只想说明此时一个字母虽然是2 byte,但是变成二进制的话只有低8位存数据,高8位就都是 0 了。

OK,上面的前提是解释我的测试的铺垫。

 
    将上面的32位存储结构分为四份(即将一个int型数据88位的分为四份,并分别标号为1234)。

假如现在有一个数组a,数组存有5个元素,假设为12345设计1的哈希过程是这样的:

 

 

最终插入12345完成!!!

    这个设计在存储数据少的时候还是比较让人满意的,但是,一看这个表格,顿时就惊呆了,这个表格说明了什么——加入hash表的长度为1000,那么取余后得到的索引位置只与存入的字符串的最后2个字母有关!!!那肯定是不行的,加入有abcdecbade存入,那肯定得撞车了。

    然后,稍微改进了一下,得到设计2

    同样的有:

嗯,现在好多了,34两个低位都与整个数组元素扯上了关系,当再加入abcdecbade后,再撞车已经几乎不可能发生了。

    现在想想,既然扯关系,那不如把关系扯得错综复杂一点,然后就得到设计3:把hash<<8改为hash<<7,即标号4的低位模块的数据没有全部移到标号3的模块,而是插一腿到原来自己呆的模块。此时,额,已经很难追寻踪迹了。。。

    那设计4怎么又加上hash<<24呢?很简单,就是让hash更复杂,但这个复杂是有道理的,目的就是让标号12的模块也与存入的整个字符串扯上关系(由表可见,标号1的模块只与少数字符数组关联),自此,便可大胆提出类似巴赫猜想的假设:如果字符数组的长度越长,那么设计4的散列效果肯定比较好。

下表为根据运行结果得到的统计数据:



 

现在只能看着数据发呆了,不管怎么说,还是能得到些信息的:

    1. 设计2和设计4的数据基本一样,也就是说hash<<8hash<<7是差不多的,hash<<7并不能增加散列效果;

    2. 在哈希表容量少、插入数组短的时候,自己的设计还是可以的,但是容量大、插入数据长的时候,那就比较劣了。

    3. hash<<24这一句并没有给设计4带来长数组的散列效果。(唉,有时候,猜想没有得到 验证也是很痛苦的)。

    4. 最重要的一点:我输了,彻底的输了,平均下来,系统的hash函数就远远抛下了我写的hash,特别是容量更大、数组长度更长的时候,差距就更明显了。

    不过,没有绝对好的hash,只有相对合适的hash

    探索路程,依然的,在路上……

 

 

 

  • 大小: 2.9 KB
  • 大小: 11.7 KB
  • 大小: 7.1 KB
  • 大小: 6.9 KB
分享到:
评论

相关推荐

    备忘:兼容ff和ie的鼠标样式+javascript字符串hash+浮动提示

    “javascript字符串hash”指的是在JavaScript中,将字符串转化为一个固定长度的数字表示,常用于数据校验、唯一标识或简化的比较操作。常见的JavaScript字符串hash算法有MD5、SHA系列等,也可以自定义简单算法,如将...

    c# asp.net 字符串加密解密的类

    在提供的压缩包文件"C#字符串加密解密"中,可能包含了关于这些加密解密方法的源代码示例,你可以下载并研究其中的实现细节,以便在自己的项目中灵活运用。记住,理解并正确使用这些工具对于确保应用程序的数据安全性...

    字符串加密(SHA)

    这段代码首先导入了Python的hashlib库,然后定义了一个函数`sha1_hash_string`,它接受一个字符串,将其编码为UTF-8,然后使用`sha1`方法生成哈希值,并返回16进制表示的哈希。最后,它打印出"Hello, World!"这个...

    用于将字符串编码成Base16Base32Base64MD5SHA1的库

    这个库,名为"用于将字符串编码成Base16Base32Base64MD5SHA1的库",提供了对几种常见编码格式和哈希函数的支持,包括Base16、Base32、Base64,以及MD5和SHA-1。这些工具在JavaScript环境中尤其有用,因为它们可以...

    java中字符串 ,Hashtable,Vector,interface的小程序

    在Java编程语言中,字符串(String)、Hashtable、Vector以及接口(interface)都是基础且重要的概念。在这个小练习中,我们分别看到了它们的使用。 首先,我们来看字符串(String)的运用。在Java中,字符串是不可变的...

    C#实现将32位MD5摘要串转换为128位二进制字符串的方法

    了解了C#中MD5摘要串转换为二进制字符串的方法后,如果对加密解密有更深入的兴趣,可以研究C#中其他相关的加密算法,如AES、DES、RSA等。同时,熟悉C#中线程、文件操作、窗体控制、数据结构和算法等方面的知识,对于...

    PHP实例开发源码—PHP 字符串加密解密程序.zip

    通过研究这个压缩包,开发者可以学习到如何在实际项目中实施字符串加密解密,提高数据安全性,并了解当前最佳的加密实践。同时,这也是一个很好的机会去熟悉和掌握PHP的加密相关函数和库,这对于任何涉及用户数据...

    基于GeoHash与聚类的共享单车动态回收点设置方法研究

    GeoHash算法则是一种地理位置编码技术,可以将一个地理位置编码为一个较短的字符串。它将地球表面划分为网格状,每个网格对应一个字符串。在共享单车动态回收点设置的研究中,GeoHash算法可以用来对骑行数据进行地理...

    密码学课设实现对文件和字符串的sha1,sha256加密

    对于字符串加密,可以直接将字符串的字节序列作为输入数据。而对于文件加密,需要读取文件内容,将其按块处理。在VC6.0环境下,可以使用标准I/O库或文件流来读取文件,然后调用哈希函数的接口进行加密。 在实现过程...

    PE导入表-函数列表-HASH值

    HASH函数将一个字符串转换为固定长度的数值,相同的字符串会产生相同的HASH值,不同字符串则有非常小的概率产生相同的HASH。在PE分析中,可以使用HASH值快速检查函数名是否存在或匹配,而无需完全比较整个字符串。 ...

    rabin-hash-function(rabin的随机多项式摘要算法)

    **Rabin哈希函数**,也称为Rabin的随机多项式摘要算法,是一种在计算机科学领域,特别是数据完整性检查和文件校验中广泛...同时,对于研究和开发新的字符串处理算法或安全协议的人员来说,这也是一个重要的基础知识。

    StringHash:使用 Swift 支持 md5、sha1 和 base64 编码的字符串扩展

    SHA1(Secure Hash Algorithm 1)同样是哈希函数,输出长度为160位,以16进制表示为40位字符串。虽然比 MD5 更安全,但也存在碰撞问题,已被建议替换为更安全的 SHA-2 家族算法。 Base64 是一种用于将二进制数据...

    webqq好友hash最新算法2013-12-4

    在提供的代码片段中,我们看到一个名为`getHash`的函数,其接受两个参数:`b`(一个整数)和`i`(一个字符串)。该函数的主要逻辑如下: 1. **初始化数组**:首先创建两个数组`a`和`j`。`a`用于存储字符串`i`的字符...

    一种hash算法的实现

    - **字符串处理技巧**:如字符串长度的获取、字符数组的遍历等,是实现哈希函数的关键步骤。 综上所述,该哈希算法实现不仅展示了内联汇编的运用技巧,同时也提供了对哈希算法设计和实现的深刻洞察,对于计算机科学...

    基于GEOHash的出租车轨迹存储和应用研究

    GEOHash是将地理位置信息编码为字符串的一种方法,它能够将二维地理坐标(经度和纬度)映射成一维字符串,并且按照一定的规则具有前缀和可分级的特性。这意味着越是接近的地理位置,它们的GEOHash编码前缀也越相似。...

    geohash-源码.rar

    在源码中,我们可以找到将经纬度转换为Geohash字符串的函数,以及反过来将Geohash字符串解析回经纬度的函数。编码过程通常涉及对坐标进行预处理、二进制编码、Base32转换,而解码则需要逆向执行这些步骤。 5. 空间...

Global site tag (gtag.js) - Google Analytics