精华内容
下载资源
问答
  • 区分哈希函数算法和加密算法

    千次阅读 2020-09-21 19:04:53
    有的时候哈希函数和加密算法我们容易混为一谈,因为哈希函数经常出现在加密场合,那在这里区分一下。 我们以公钥加密为例,对于加密来讲分为两方面,如果A想要给B发一条私密消息,那么A需要用B的公钥加密消息发给B...

    有的时候哈希函数和加密算法我们容易混为一谈,因为哈希函数经常出现在加密场合,那在这里区分一下。

    我们以公钥加密为例,对于加密来讲分为两方面,如果A想要给B发一条私密消息,那么A需要用B的公钥加密消息发给B,因为A不想人让别人看到消息内容,若A拿自己的私钥,则所有人都可以看到,而这个是加密的另一个方面数字签名,

    即A想给B发一个消息,并且要让B知道这个消息就是A发给他的,那么A要用自己的私钥加密"名字"给这个加密消息做一个sign,B收到消息后,首先用A的公钥把sign解密之后发现是A的"名字",知道这个消息一定是A发送的,然后用自己的私钥把消息解密就得到了A给他的私信。

    这是加密算法的所用,是双向的,加密后可以解密

    而哈希函数是单向的,即哈希函数对一个消息"加密"后,无法"解密",那我们用它来干嘛,

    比如,我们加密时的私钥,一般加密是私钥是很长的一种二进制,但是我们时不回去记几百位的二进制的,所以 就用哈希函数把我们常用的不同长度的符号组合变换成需要的二进制,比如有的人常用123456作为私钥(密码),所以我们只需要记住这个私钥,以后需要的时候通过哈希函数把123456转换成如百位的二进制(当然这个是通过机器来计算的),所以说哈希函数有自己应用的场景,当然我们可以找一个加密算法把123456加密成需要的片段,但是加密算法总是有对应的解密算法的,这个是我们私钥不需要的,所以采用单向的哈希函数。

    所以总结来说:加密算法是对消息进行加密,或者给消息加一个sign;哈希函数是用来产生单向的固定长度片段,这种片段是不需要恢复原来元素的。

    展开全文
  • 这是一个哈希函数算法_SHA1的c++语言实现的程序,实验结果表明非常好,有助于RSA的理解。
  • 字符串哈希函数算法的PHP 实现

    千次阅读 2008-01-04 14:08:00
    或许还有朋友不清楚字符串的哈希函数到底有什么用,这个用处呢,就是将字符串转换成数字,同时让所得数字尽量平均的分布在容器中,换句话说就是让字符串得到相同数字这种情况尽可能少的出现。当然咯...容器太小,...

    恩...或许还有朋友不清楚字符串的哈希函数到底有什么用,这个用处呢,就是将字符串转换成数字,同时让所得数字尽量平均的分布在容器中,换句话说就是让字符串得到相同数字这种情况尽可能少的出现。当然咯...容器太小,内容太多那么再好的算法也没法避免出现冲突 = =b

    从网上找到的哈希函数基本上都是C算法的...最后只好从C and Java 算法中整理 and 测试了这些 PHP中的实现方法。有几个经典的算法在 PHP 下会有问题,字符串一长就会全部取 0,那些我就没有再列出来了。代码就看下面咯:

    PHP:
    1. function DJBHash ( $str ) // 0.22
    2. {
    3. $hash = 0;
    4. $n = strlen ( $str );
    5. for ( $i = 0; $i < $n; $i++ )
    6. {
    7. $hash += ( $hash << 5 ) + ord ( $str [ $i ] );
    8. }
    9. return $hash % 701819;
    10. }
    11.  
    12. function ELFHash ( $str ) // 0.35
    13. {
    14. $hash = $x = 0;
    15. $n = strlen ( $str );
    16.  
    17. for ( $i = 0; $i < $n; $i++ )
    18. {
    19. $hash = ( $hash << 4 ) + ord ( $str [ $i ] );
    20. if ( ( $x = $hash & 0xf0000000 ) != 0 )
    21. {
    22. $hash ^= ( $x>> 24 );
    23. $hash &= ~ $x;
    24. }
    25. }
    26. return $hash % 701819;
    27. }
    28.  
    29. function JSHash ( $str ) // 0.23
    30. {
    31. $hash = 0;
    32. $n = strlen ( $str );
    33.  
    34. for ( $i = 0; $i < $n; $i++ )
    35. {
    36. $hash ^= ( ( $hash << 5 ) + ord ( $str [ $i ] ) + ( $hash>> 2 ) );
    37. }
    38. return $hash % 701819;
    39. }
    40.  
    41. function SDBMHash ( $str ) // 0.23
    42. {
    43. $hash = 0 ;
    44. $n = strlen ( $str );
    45.  
    46. for ( $i = 0; $i < $n; $i++ )
    47. {
    48. $hash = ord ( $str [ $i ] ) + ( $hash << 6 ) + ( $hash << 16 ) - $hash;
    49. }
    50. return $hash % 701819;
    51. }
    52.  
    53. function APHash ( $str ) // 0.30
    54. {
    55. $hash = 0 ;
    56. $n = strlen ( $str );
    57.  
    58. for ( $i = 0; $i < $n; $i++ )
    59. {
    60. if ( ( $i & 1 ) == 0 )
    61. {
    62. $hash ^= ( ( $hash << 7 ) ^ ord ( $str [ $i ] ) ^ ( $hash>> 3 ) );
    63. }
    64. else
    65. {
    66. $hash ^= ( ~ ( ( $hash << 11 ) ^ ord ( $str [ $i ] ) ^ ( $hash>> 5 ) ) );
    67. }
    68. }
    69. return $hash % 701819;
    70. }
    71.  
    72. function DEKHash ( $str ) // 0.23
    73. {
    74. $n = strlen ( $str );
    75. $hash = $n;
    76.  
    77. for ( $i = 0; $i < $n; $i++ )
    78. {
    79. $hash = ( ( $hash << 5 ) ^ ( $hash>> 27 ) ) ^ ord ( $str [ $i ] );
    80. }
    81. return $hash % 701819;
    82. }
    83.  
    84. function FNVHash ( $str ) // 0.31
    85. {
    86. $hash = 0;
    87. $n = strlen ( $str );
    88.  
    89. for ( $i = 0; $i < $n; $i++ )
    90. {
    91. $hash *= 0x811C9DC5;
    92. $hash ^= ord ( $str [ $i ] );
    93. }
    94.  
    95. return $hash % 701819;
    96. }
    97.  
    98. function PJWHash ( $str ) // 0.33
    99. {
    100. $hash = $test = 0;
    101. $n = strlen ( $str );
    102.  
    103. for ( $i = 0; $i < $n; $i++ )
    104. {
    105. $hash = ( $hash << 4 ) + ord ( $str [ $i ] );
    106.  
    107. if ( ( $test = $hash & - 268435456 )  != 0 )
    108. {
    109. $hash = ( ( $hash ^ ( $test>> 24 ) ) & (~- 268435456 ) );
    110. }
    111. }
    112.  
    113. return $hash % 701819;
    114. }
    115.  
    116. function PHPHash ( $str ) // 0.34
    117. {
    118. $hash = 0;
    119. $n = strlen ( $str );
    120.  
    121. for ( $i = 0; $i < $n; $i++ )
    122. {
    123. $hash = ( $hash << 4 ) + ord ( $str [ $i ] );
    124. if ( ( $g = ( $hash & 0xF0000000 ) ) )
    125. {
    126. $hash = $hash ^ ( $g>> 24 );
    127. $hash = $hash ^ $g;
    128. }
    129. }
    130. return $hash % 701819;
    131. }
    132.  
    133. function OpenSSLHash ( $str ) // 0.22
    134. {
    135. $hash = 0;
    136. $n = strlen ( $str );
    137.  
    138. for ( $i = 0; $i < $n; $i++ )
    139. {
    140. $hash ^= ( ord ( $str [ $i ] ) << ( $i & 0x0f ) );
    141. }
    142. return $hash % 701819;
    143. }
    144.  
    145. function MD5Hash ( $str ) // 0.050
    146. {
    147. $hash = md5 ( $str );
    148. $hash = $hash [ 0 ] | ( $hash [ 1 ] << 8 ) | ( $hash [ 2 ] << 16 ) | ( $hash [ 3 ] << 24 ) | ( $hash [ 4 ] << 32 ) | ( $hash [ 5 ] << 40 ) | ( $hash [ 6 ] << 48 ) | ( $hash [ 7 ] << 56 );
    149. return $hash % 701819;
    150. }

     

    算法的一些说明:

    1. 函数后面注释中是我本地测试的执行1000次的速度(单位:s),可以看出来MD5Hash是最快的,而且要比其他函数快很多很多...但是从这个函数的算法也可以看出来,它仅仅是依赖于md5后字符串的前7个字符,也就是说如果前7个字符相同的话那么获得的hash值是完全一样的,所以实际来说它的分布情况是不太令人信任的....如果按照32个字符来计算的话速度那就远远的慢于其他算法了...
    2. 除了MD5Hash,其他算法都会受到字符串长度的影响,越长越慢,我测试用的是10个字符的英文。
    3. 每个函数最后的 return $hash % 701819; 中 701819 表示是哈希的最大容积,也就是说这些哈希函数最后得到的数字范围是0~701819,这个数字是可以改的一般认为使用一个大的质数结果的分布会是比较均匀的,在 701819 附近的几个建议的值是:175447, 350899, 1403641, 2807303, 5614657。

      或许你又问了,这个到底可以用来做什么呢...
      呵呵,我来解释一下我为什么要整理 and 测试这些哈希算法,我在写多用户 Blog,恩...之前的日志里面也有提过,多用户 Blog 一般都有一个功能,那就是使用一个英文和数字组合的用户名来作为 Blog 的地址(二级域名或者目录)。那么就有一个问题了,如何根据用户名来获取用户的 ID,多一次查询吗?有了哈希函数就不用了,使用哈希函数处理用户名,得到一个数字,再对数字做一定的处理(我是按照2位分割成层次的目录,目的是防止一个目录下有太多的文件而影响磁盘检索速度),然后就形成了一个路径,把对应的ID保存在这个路径下的文件内(我个人推荐用户名做文件名),这样就可以根据用户名来直接获得用户的ID,不需要查询,用户名做文件名,所以即使最后结果相同也是在不同的文件中,所以可以不用担心出现碰撞。

      当然...如果你的系统完全是根据用户名来操作那当我前面这些都没说 = =b,悄悄的非议一句 SELECT 也是数字比字符串要快一些地。

      我选择的是DJB算法,等以后上线后如果测试MD5分布还算可以接受的话再考虑换用。

      从这里也可以看出来其实哈希对于分布还是很有用地,呵呵,可以用来作缓存,静态或者其他需要分布存储的东西上面,这都要看你怎么用了。

    展开全文
  • 构造哈希函数的目标是使得到的关键字的哈希地址尽可能均匀地分布在n个连续内存单元地址上,从而减少地址冲突。 根据关键字的结构和分布的不同,可构造出许多不同的哈希函数。 常用的构造哈希函数方法有 1、除...

     

    构造哈希函数的目标是使得到的关键字的哈希地址尽可能均匀地分布在n个连续内存单元地址上,从而减少地址冲突。

    根据关键字的结构和分布的不同,可构造出许多不同的哈希函数。

     

    常用的构造哈希函数方法有

    1、除留余数法

    除留余数法是用关键字k除以某个不大于哈希长度m的数p (p<=m),将所得的余数作为哈希地址的方法。

    h(k) = k mod p

    这种方法的关键是选好p,使得元素集合中的每一个关键字通过该函数转换后映射到哈希表范围内的任意地址上的概率相等,从而减少发生冲突的可能性。

    2、平方取中法

    取关键字平方后分布均匀的几位作为哈希地址的方法

    3、折叠法

    将关键字分割成位数相同的及部分,然后取这几部分的叠加和(舍去进位)作为哈希地址。当关键字的位数很多且每一位的值都随机出现时,则折叠法可得冲突较少的哈希地址。

    此外还有数字分析法、直接定址法等。

     

    选择哈希函数时,通常考虑的因素有:

    • 计算哈希函数所需的时间
    • 关键字的长度
    • 哈希表的大小
    • 关键字的分布
    • 记录的查找频率

     

    常用的两种处理冲突的方法 开放定址法和链地址法。

    开放定址法

     

    链地址法

    将所有关键字为同义词的记录存储在同一线性链表中。哈希表每个单元中存放的不再是元素本身,二十相应同义词单链表的头指针。

    展开全文
  • 一、什么是哈希(Hash) 哈希也称“散列”函数或“杂凑”函数。它是一个不可逆的单向映射,将任意长度的输入消息M...这是哈希函数安全性的基础。 灵敏性:对输入数据敏感,哪怕只改了一个Bit,得到的哈希值也大不相同

    目录

    一、什么是哈希(Hash)

    二、哈希的原理和特点

    三、哈希的实际用途

    四、典型的哈希函数

    (一)MD5

    (二)SHA

    五、Hash构造函数的方法


    一、什么是哈希(Hash)

    哈希也称“散列”函数或“杂凑”函数。它是一个不可逆的单向映射,将任意长度的输入消息M(或文件F)映射成为一个较短的定长哈希值H(M),也叫散列值(HashValue)、杂凑值或消息摘要。可见,这是一种单向密码体制,只有加密过程,没有解密过程(因此Hash求逆很困难)。

    二、哈希的原理和特点

    1. 单向性:从哈希值不能反向推导原始数据(计算不可行),即从哈希输出无法倒推输入的原始数值。这是哈希函数安全性的基础。
    2. 灵敏性:对输入数据敏感,哪怕只改了一个Bit,得到的哈希值也大不相同。换言之,消息M的任何改变都会导致哈希值H(M)发生改变。
    3. 易压易算:Hash本质上是把一个大范围集合映射到另一个小范围集合。故输入值的个数必须与小范围相当或者更小,不然冲突就会很多。所以,哈希算法执行效率要高,散列结果要尽量均衡。
    4. 抗碰撞性:理想Hash函数是无碰撞的,但实际上很难做到这一点。有两种抗碰撞性:一种是弱抗碰撞性,即对于给定的消息,要发现另一个消息,满足在计算上是不可行的;另一种是强抗碰撞性,即对于任意一对不同的消息,使得在计算上也是不可行的。

    也可以这么理解正向快速、逆向困难、输入敏感、冲突避免

    三、哈希的实际用途

    Hash能把一个大范围映射到一个小范围,能对输入数据或文件进行校验,还可用于查找等。具体的:

    1. 唯一标识或数据检验:能够对输入数据或文件进行校验,判断是否相同或是否被修改。如图片识别,可针对图像二进制流进行摘要后MD5,得到的哈希值作为图片唯一标识;如文件识别,服务器在接受文件上传时,对比两次传送文件的哈希值,若相同则无须再次上传(传统的奇偶校验和CRC校验一定程度上能检测并纠正数据传输中的信道误码,但没有抗数据篡改的能力)。
    2. 安全加密:对于敏感数据比如密码字段进行MD5或SHA加密传输。哈希算法还可以检验信息的拥有者是否真实。如,用保存密码的哈希值代替保存密码,基本可以杜绝泄密风险。
    3. 数字签名。由于非对称算法的运算速度较慢,所以在数字签名协议中,单向散列函数扮演了一个重要的角色。对Hash值,又称“数字摘要”进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。
    4. 散列函数:是构造散列表的关键。它直接决定了散列冲突的概率和散列表的性质。不过相对哈希算法的其他方面应用,散列函数对散列冲突要求较低,出现冲突时可以通过开放寻址法或链表法解决冲突。对散列值是否能够反向解密要求也不高。反而更加关注的是散列的均匀性,即是否散列值均匀落入槽中以及散列函数执行的快慢也会影响散列表性能。所以散列函数一般比较简单,追求均匀和高效。
    5. *负载均衡:常用的负载均衡算法有很多,比如轮询、随机、加权轮询。如何实现一个会话粘滞的负载均衡算法呢?可以通过哈希算法,对客户端IP地址或会话SessionID计算哈希值,将取得的哈希值与服务器列表大小进行取模运算,最终得到应该被路由到的服务器编号。这样就可以把同一IP的客户端请求发到同一个后端服务器上。
    6. *数据分片:比如统计1T的日志文件中“搜索关键词”出现次数该如何解决?我们可以先对日志进行分片,然后采用多机处理,来提高处理速度。从搜索的日志中依次读取搜索关键词,并通过哈希函数计算哈希值,然后再跟n(机器数)取模,最终得到的值就是应该被分到的机器编号。这样相同哈希值的关键词就被分到同一台机器进行处理。每台机器分别计算关键词出现的次数,再进行合并就是最终结果。这也是MapReduce的基本思想。再比如图片识别应用中给每个图片的摘要信息取唯一标识然后构建散列表,如果图库中有大量图片,单机的hash表会过大,超过单机内存容量。这时也可以使用分片思想,准备n台机器,每台机器负责散列表的一部分数据。每次从图库取一个图片,计算唯一标识,然后与机器个数n求余取模,得到的值就是被分配到的机器编号,然后将这个唯一标识和图片路径发往对应机器构建散列表。当进行图片查找时,使用相同的哈希函数对图片摘要信息取唯一标识并对n求余取模操作后,得到的值k,就是当前图片所存储的机器编号,在该机器的散列表中查找该图片即可。实际上海量数据的处理问题,都可以借助这种数据分片思想,突破单机内存、CPU等资源限制。
    7. *分布式存储:一致性哈希算法解决缓存等分布式系统的扩容、缩容导致大量数据搬移难题。

    四、典型的哈希函数

    常见Hash算法有MD5和SHA系列,目前MD5和SHA1已经被破解,一般推荐至少使用SHA2-256算法。

    (一)MD5

    MD5属于Hash算法中的一种,它输入任意长度的信息,在处理过程中以512位输入数据块为单位,输出为128位的信息(数字指纹)。常用场景:

    1、防篡改,保障文件传输可靠性:如SVN中对文件的控制;文件下载过程中,网站提供MD5值供下载后判断文件是否被篡改;BT中对文件块进行校验的功能。

    2、增强密码保存的安全性:例如网站将用户密码的MD5值保存,而不是存储明文用户密码,当然,还会加SALT,进一步增强安全性。

    3、数字签名:在部分网上赌场中,使用MD5算法来保证过程的公平性,并使用随机串进行防碰撞,增加解码难度。

    算法实现过程:

    第一步:消息填充,补长到512的倍数。最后64位为消息长度(填充前的长度)的低64位,一定要补长(64+1~512),内容为100…0(如若消息长448,则填充512+64)。

    第二步:分割,把结果分割为512位的块:Y0,Y1,…(每一个有16个32比特长字)。

    第三步:计算,初始化MD buffer,128位常量(4个32bit字),进入循环迭代,共L次。每次一个输入128位,另一个输入512位,结果输出128位,用于下一轮输入。

    第四步:输出,最后一步的输出即为散列结果128位。

    (二)SHA-1  Secure Hash Algorithm

    安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64b的消息,SHA-1将输入流按照每块512b(64B)进行分块,并产生20B或160b的信息摘要。

    https://images2015.cnblogs.com/blog/929265/201607/929265-20160701092331874-1851324775.png

    1.补位

    消息补位使其长度在对512取模以后的余数是448。也就是说,(补位后的消息长度)% 512 = 448。即使长度已经满足对512取模后余数是448,补位也必须要进行。

    补位是这样进行的:先补一个1,然后再补0,直到长度满足对512取模后余数是448。总而言之,补位是至少补一位,最多补512位。还是以前面的“abc”为例显示补位的过程。

    原始信息:  011000010110001001100011

    补位第一步:0110000101100010011000111,首先补一个“1”

    补位第二步:01100001011000100110001110…..0,然后补423个“0”

    我们可以把最后补位完成后的数据用16进制写成下面的样子,确保是448b:

    61626380000000000000000000000000

    00000000000000000000000000000000

    00000000000000000000000000000000

    0000000000000000

    2.补长度

    补长度是将原始数据的长度补到已经进行了补位操作的消息后面。通常用一个64位的数据来表示原始消息的长度。如果消息长度不大于2^64,那么第一个字就是0。

    在进行了补长度的操作以后,整个消息就变成下面这样了(16进制格式):

    61626380000000000000000000000000

    00000000000000000000000000000000

    00000000000000000000000000000000

    00000000000000000000000000000018

    如果原始的消息长度超过了512,我们需要将它补成512的倍数。然后我们把整个消息分成一个一个512位的数据块。分别处理每一个数据块,从而得到消息摘要。

    3.使用的常量

    一系列的常量字K(0),K(1),...,K(79),如果以16进制给出。它们如下:

    Kt=0x5A827999(0<=t<=19)

    Kt=0x6ED9EBA1(20<=t<=39)

    Kt=0x8F1BBCDC(40<=t<=59)

    Kt=0xCA62C1D6(60<=t<=79).

    4.需要使用的函数

    在SHA1中我们需要一系列的函数。每个函数ft(0<=t<=79)都操作32位字B,C,D并且产生32位字作为输出。

    ft(B,C,D)可以如下定义:

    ft(B,C,D)=(BANDC)or((NOTB)ANDD)(0<=t<=19)

    ft(B,C,D)=BXORCXORD(20<=t<=39)

    ft(B,C,D)=(BANDC)or(BANDD)or(CANDD)(40<=t<=59)

    ft(B,C,D)=BXORCXORD(60<=t<=79).

    5.计算消息摘要

    必须使用进行了补位和补长度后的消息来计算消息摘要。计算需要两个缓冲区,每个都由5个32位的字组成,还需要一个80个32位字的缓冲区。第一个5个字的缓冲区被标识为A,B,C,D,E。第一个5个字的缓冲区被标识为H0,H1,H2,H3,H4。80个字的缓冲区被标识为W0,W1,...,W79。

    另外还需要一个一个字的TEMP缓冲区。

    为了产生消息摘要,在第4部分中定义的16个字的数据块M1,M2,...,Mn会依次进行处理,处理每个数据块Mi包含80个步骤。


    在处理每个数据块之前,缓冲区{Hi}被初始化为下面的值(16进制)

    H0=0x67452301

    H1=0xEFCDAB89

    H2=0x98BADCFE

    H3=0x10325476

    H4=0xC3D2E1F0.


    现在开始处理M1,M2,...,Mn。为了处理Mi,需要进行下面的步骤

    (1)将Mi分成16个字W0,W1,...,W15,W0是最左边的字

    (2)对于t=16到79令Wt=S1(Wt-3XORWt-8XORWt-14XORWt-16).

    (3)令A=H0,B=H1,C=H2,D=H3,E=H4.

    (4)对于t=0到79,执行下面的循环

    TEMP=S5(A)+ft(B,C,D)+E+Wt+Kt;

    E=D;D=C;C=S30(B);B=A;A=TEMP;

    (5)令H0=H0+A,H1=H1+B,H2=H2+C,H3=H3+D,H4=H4+E.

    在处理完所有的Mn,后,消息摘要是一个160位的字符串,以下面的顺序标识H0H1H2H3H4。

    (三)SHA-2系列

    SHA-2是六个不同算法的合称,包括:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。除了生成摘要的长度、循环运行的次数等一些微小差异外,这些算法的基本结构是一致的。对于任意长度的消息,SHA256都会产生一个256bit长的消息摘要。

    详细参见:sha256算法原理 - Practical - 博客园

    至今尚未出现对SHA-2有效的攻击,SHA-2和SHA-1并没有接受公众密码社区的详细检验,所以它们的密码安全性还不被广泛信任。

    总体上,HAS-256与MD4、MD5以及HSA-1等哈希函数的操作流程类似,在哈希计算之前首先要进行以下两个步骤:

    • 对消息进行补位处理,最终的长度是512位的倍数;
    • 以512位为单位对消息进行分块为M1,M2,…,Mn
    • 处理消息块:从一个初始哈希H0开始,迭代计算:Hi = Hi-1 + CMi(Hi-1)

    其中C是SHA256的压缩函数,+是mod 2^32加法,Hn是消息区块的哈希值。

    五、Hash构造函数的方法

    1.直接定址法(极少用)

    以数据元素关键字k本身或它的线性函数作为它的哈希地址,即:H(k)=k或H(k)=a×k+b;(其中a,b为常数)。

    此法仅适合于:地址集合的大小==关键字集合的大小,其中a和b为常数。

    2.数字分析法

    假设关键字集合中的每个关键字都是由s位数字组成(u1,u2,…,us),分析关键字集中的全体,并从中提取分布均匀的若干位或它们的组合作为地址。数字分析法是取数据元素关键字中某些取值较均匀的数字位作为哈希地址的方法。即当关键字的位数很多时,可以通过对关键字的各位进行分析,丢掉分布不均匀的位,作为哈希值。它只适合于所有关键字值已知的情况。通过分析分布情况把关键字取值区间转化为一个较小的关键字取值区间。

    此法适于:能预先估计出全体关键字的每一位上各种数字出现的频度。

    3.折叠法

    将关键字分割成若干部分,然后取它们的叠加和为哈希地址。两种叠加处理的方法:移位叠加:将分割后的几部分低位对齐相加;边界叠加:从一端沿分割界来回折叠,然后对齐相加。

    所谓折叠法是将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位),这方法称为折叠法。这种方法适用于关键字位数较多,而且关键字中每一位上数字分布大致均匀的情况。

    折叠法中数位折叠又分为移位叠加和边界叠加两种方法,移位叠加是将分割后是每一部分的最低位对齐,然后相加;边界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。

    此法适于:关键字的数字位数特别多。

    4.平方取中法

    这是一种常用的哈希函数构造方法。这个方法是先取关键字的平方,然后根据可使用空间的大小,选取平方数是中间几位为哈希地址。哈希函数H(key)=“key2的中间几位”因为这种方法的原理是通过取平方扩大差别,平方值的中间几位和这个数的每一位都相关,则对不同的关键字得到的哈希函数值不易产生冲突,由此产生的哈希地址也较为均匀。

    此法适于:关键字中的每一位都有某些数字重复出现频度很高的现象。

    5.减去法



    减去法是数据的键值减去一个特定的数值以求得数据存储的位置。

    6.基数转换法

    将十进制数X看作其他进制,比如十三进制,再按照十三进制数转换成十进制数,提取其中若干为作为X的哈希值。一般取大于原来基数的数作为转换的基数,并且两个基数应该是互素的。

    7.除留余数法

    假设哈希表长为m,p为小于等于m的最大素数,则哈希函数为h(k)=k%p,其中%为模p取余运算。除留余数法的模p取不大于表长且最接近表长m素数时效果最好,且p最好取1.1n~1.7n之间的一个素数(n为存在的数据元素个数)。

    8.随机数法

    设定哈希函数为:H(key)=Random(key)其中,Random为伪随机函数

    此法适于:对长度不等的关键字构造哈希函数。

    9.随机乘数法

    亦称为“乘余取整法”。随机乘数法使用一个随机实数f,0≤f<1,乘积f*k的分数部分在0~1之间,用这个分数部分的值与n(哈希表的长度)相乘,乘积的整数部分就是对应的哈希值,显然这个哈希值落在0~n-1之间。其表达公式为:Hash(k)=「n*(f*k%1)」其中“f*k%1”表示f*k的小数部分,即f*k%1=f*k-「f*k」

    此方法的优点是对n的选择不很关键。通常若地址空间为p位就是选n=2p.Knuth对常数f的取法做了仔细的研究,他认为f取任何值都可以,但某些值效果更好。如f=(-1)/2=0.6180329...比较理想。

    10.字符串数值哈希法

    把字符串的前10个字符的ASCⅡ值之和对N取摸作为Hash地址,只要N较小,Hash地址将较均匀分布[0,N]区间内。对于N很大的情形,可使用ELFHash(ExecutableandLinkingFormat,ELF,可执行链接格式)函数,它把一个字符串的绝对长度作为输入,并通过一种方式把字符的十进制值结合起来,对长字符串和短字符串都有效,这种方式产生的位置可能不均匀分布。

    11.旋转法

    旋转法是将数据的键值中进行旋转。旋转法通常并不直接使用在哈希函数上,而是搭配其他哈希函数使用。

    展开全文
  • LintCode 128. 哈希函数 JavaScript算法

    千次阅读 2020-09-22 09:43:02
    一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基于33的一个大整数,比如: hashcode(“abcd”) = (ascii(a) * 33^3 + ascii(b) * 33^2 + ascii© 33 + ascii(d)) % HASH_SIZE = (97 33^3 + 98 * 33^...
  • 哈希函数,是用来计算存储数据的哈希值的,根据存储数据的类型,可以设计不同的哈希函数。一个好的哈希函数(让哈希表效率高的函数),一般都具备下面两个特点: 速度快(别计算一个哈希值计算了半天,导致效率很低...
  • 散列函数(哈希函数)算法

    千次阅读 2014-11-07 16:19:19
    常用字符串哈希函数有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。 C++代码 对于以上几种哈希函数,对其进行了一个小小的评测。 Hash函数 数据1 数据2...
  • 哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者消息摘要(Message Digest)。它是一种单向密码体制,即一个从明文...
  • 我的机器学习教程「美团」算法工程师带你入门机器学习 已经开始更新了,欢迎大家订阅~ 任何关于算法、编程、AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑...
  • 那这个哈希函数怎么实现呢,根据前面一篇博客【JS数据结构】认识哈希表,我们已经认识了什么是哈希表以及为什么需要设计一个哈希函数。 其实就是要达到两个目的: 能够快速地计算,快速地获取hashC...
  • 2005年,王小云和国内专家设计了我国首个哈希函数算法标准SM3。 如今,SM3已为我国多个行业保驾护航。 11月16日傍晚,梳着干练短发、带着典型学者风采的王小云出现在2019未来科学大奖周。 问及此次获奖的感受,这位...
  • 哈希函数设计的艺术,详细讲述各种哈希算法的应用场景和效率。
  • // 哈希函数/散列算法 // 根据某个值进行hash值计算,确保唯一性 public class HashUtils { private static final String ALGORITHM = "SHA-256"; public static String sha256Hex(byte[] bytes){ ...
  • 哈希函数

    2017-11-13 20:07:12
    需求: 在数据结构中,哈希函数是...一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基于33的一个大整数,比如: hashcode("abcd") = (ascii(a) * 333 + ascii(b) * 332 + ascii(c) *33 + asc
  • 哈希查找的第一步就是使用哈希函数将键映射成索引。这种映射函数就是哈希函数。如果有一个数组大小为M,那么就需要一个能够将任意键转换为该数组范围内的索引(0~M-1)的哈希函数哈希函数需要易于计算并且能够均匀...
  • 哈希函数: 常见的功能就是 打乱分布 均匀随机 输入无穷大 输出却在一定范围内  即使出现碰撞 但是每个输出对应的输入个数 概率均匀分布 没有太大偏向 一个重要的性质: 如果在input域上均匀分布 那么经过...
  • 最小完美哈希函数(BDZ 算法) 需要存储 g 数组和 h0, h1, h3 函数 g 中的每个元素都在 [0, 3] 之间所以需要两位 对于一个键,哈希值 = { i = (g[h0(key)] + g[h1(key)] + g[h2(key)]) % 3 return hi(key) }
  • 哈希函数,又叫散列函数、散列算法,是一种从任何一种数据中创建小的数字“指纹”(也叫做摘要)的方法。什么意思呢?就是说,你输入任何长度、任何内容的数据,哈希函数输出固定长度、固定格式的结果,这个结果类似...
  • 什么哈希? 比方我有个原始值,“老铁双击666”, 通过某种算法(比如java的hasecode(获得变量的物理信息))得到的“哈希码”是“254874125”(将字符串转换成尽可能不重复的int类型数字), 然后通过哈希算法(如...
  • 算法6-1:哈希函数

    千次阅读 2014-06-13 20:05:07
    在上章节中已经介绍了通过红黑树实现键值对数组的查询操作,复杂度是logN。有没有性能更好的算法呢?答案是有。...哈希函数 目标 根据对象中的成员变量的值,按照一定的规则计算出一个

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,454
精华内容 52,181
关键字:

哈希函数算法包括什么