文档库 最新最全的文档下载
当前位置:文档库 › 几种字符串哈希HASH算法的性能比较

几种字符串哈希HASH算法的性能比较

几种字符串哈希HASH算法的性能比较
几种字符串哈希HASH算法的性能比较

几种字符串哈希HASH算法的性能比较

2011年01月26日星期三 19:40

这不就是要找hash table的hash function吗?

1 概述

链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但Hash链表查找的时间效率为O(1)。

设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的算法无法比拟的,Hash 链表的构造和冲突的不同实现方法对效率当然有一定的影响,然而Hash函数是Hash链表最核心的部分,本文尝试分析一些经典软件中使用到的字符串 Hash函数在执行效率、离散性、空间利用率等方面的性能问题。

2 经典字符串Hash函数介绍

作者阅读过大量经典软件原代码,下面分别介绍几个经典软件中出现的字符串Hash函数。

2.1 PHP中出现的字符串Hash函数

static unsigned long hashpjw(char *arKey, unsigned int nKeyLength) {

unsigned long h = 0, g;

char *arEnd=arKey+nKeyLength;

while (arKey < arEnd) {

h = (h << 4) + *arKey++;

if ((g = (h & 0xF0000000))) {

h = h ^ (g >> 24);

h = h ^ g;

}

}

return h;

}

2.2 OpenSSL中出现的字符串Hash函数

unsigned long lh_strhash(char *str)

{

int i,l;

unsigned long ret=0;

unsigned short *s;

if (str == NULL) return(0);

l=(strlen(str)+1)/2;

s=(unsigned short *)str;

for (i=0; i

ret^=(s[i]<<(i&0x0f));

return(ret);

} */

/* The following hash seems to work very well on normal text strings * no collisions on /usr/dict/words and it distributes on %2^n quite * well, not as good as MD5, but still good.

*/

unsigned long lh_strhash(const char *c)

{

unsigned long ret=0;

long n;

unsigned long v;

int r;

if ((c == NULL) || (*c == '\0'))

return(ret);

/*

unsigned char b[16];

MD5(c,strlen(c),b);

return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));

*/

n=0x100;

while (*c)

{

v=n|(*c);

n+=0x100;

r= (int)((v>>2)^v)&0x0f;

ret=(ret<>(32-r));

ret&=0xFFFFFFFFL;

ret^=v*v;

c++;

}

return((ret>>16)^ret);

}

在下面的测量过程中我们分别将上面的两个函数标记为OpenSSL_Hash1和OpenSSL_Hash2,至于上面的实现中使用MD5算法的实现函数我们不作测试。2.3 MySql中出现的字符串Hash函数

#ifndef NEW_HASH_FUNCTION

/* Calc hashvalue for a key */

static uint calc_hashnr(const byte *key,uint length)

{

register uint nr=1, nr2=4;

while (length--)

{

nr^= (((nr & 63)+nr2)*((uint) (uchar) *key++))+ (nr << 8);

nr2+=3;

}

return((uint) nr);

}

/* Calc hashvalue for a key, case indepenently */

static uint calc_hashnr_caseup(const byte *key,uint length)

{

register uint nr=1, nr2=4;

while (length--)

{

nr^= (((nr & 63)+nr2)*((uint) (uchar) toupper(*key++)))+ (nr << 8);

nr2+=3;

}

return((uint) nr);

}

#else

/*

* Fowler/Noll/Vo hash

*

* The basis of the hash algorithm was taken from an idea sent by email to the

* IEEE Posix P1003.2 mailing list from Phong Vo (kpv@https://www.wendangku.net/doc/494231012.html,) and

* Glenn Fowler (gsf@https://www.wendangku.net/doc/494231012.html,). Landon Curt Noll

(chongo@https://www.wendangku.net/doc/494231012.html,)

* later improved on their algorithm.

*

* The magic is in the interesting relationship between the special prime * 16777619 (2^24 + 403) and 2^32 and 2^8.

*

* This hash produces the fewest collisions of any function that we've seen so

* far, and works well on both numbers and strings.

*/

uint calc_hashnr(const byte *key, uint len)

{

const byte *end=key+len;

uint hash;

for (hash = 0; key < end; key++)

{

hash *= 16777619;

hash ^= (uint) *(uchar*) key;

}

return (hash);

}

uint calc_hashnr_caseup(const byte *key, uint len)

{

const byte *end=key+len;

uint hash;

for (hash = 0; key < end; key++)

{

hash *= 16777619;

hash ^= (uint) (uchar) toupper(*key);

}

return (hash);

}

#endif

Mysql中对字符串Hash函数还区分了大小写,我们的测试中使用不区分大小写的字符串Hash函数,另外我们将上面的两个函数分别记为MYSQL_Hash1和MYSQL_Hash2。

2.4 另一个经验字符串Hash函数

unsigned int hash(char *str)

{

register unsigned int h;

register unsigned char *p;

for(h=0, p = (unsigned char *)str; *p ; p++)

h = 31 * h + *p;

return h;

}

3 测试及结果

3.1 测试说明

从上面给出的经典字符串Hash函数中可以看出,有的涉及到字符串大小敏感问题,我们的测试中只考虑字符串大小写敏感的函数,另外在上面的函数中有的函数需要长度参数,有的不需要长度参数,这对函数本身的效率有一定的影响,我们的测试中将对函数稍微作一点修改,全部使用长度参数,并将函数内部出现的计算长度代码删除。

我们用来作测试用的Hash链表采用经典的拉链法解决冲突,另外我们采用静态分配桶(Hash链表长度)的方法来构造Hash链表,这主要是为了简化我们的实

现,并不影响我们的测试结果。

测试文本采用单词表,测试过程中从一个输入文件中读取全部不重复单词构造一个Hash表,测试内容分别是函数总调用次数、函数总调用时间、最大拉链长度、平均拉链长度、桶利用率(使用过的桶所占的比率),其中函数总调用次数是指Hash函数被调用的总次数,为了测试出函数执行时间,该值在测试过程中作了一定的放大,函数总调用时间是指Hash函数总的执行时间,最大拉链长度是指使用拉链法构造链表过程中出现的最大拉链长度,平均拉链长度指拉链的平均长度。

测试过程中使用的机器配置如下:

PIII600笔记本,128M内存,windows 2000 server操作系统。

3.2 测试结果

以下分别是对两个不同文本文件中的全部不重复单词构造Hash链表的测试结果,测试结果中函数调用次数放大了100倍,相应的函数调用时间也放大了100倍。

从上表可以看出,这些经典软件虽然构造字符串Hash函数的方法不同,但是它们的效率都是不错的,相互之间差距很小,读者可以参考实际情况从其中借鉴使用。

哈希算法散列

计算机算法领域 基本知识 Hash,一般翻译做“散列”,也有直接音译为”哈希“的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 HASH主要用于信息安全领域中加密算法,他把一些不同长度的信息转化成杂乱的128位的编码里,叫做HASH值. 也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系 基本概念 * 若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为散列函数(Hash function),按这个思想建立的表为散列表。 * 对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。具有相同函数值的关键字对该散列函数来说称做同义词。综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象” 作为记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。 * 若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为均匀散列函数(Uniform Hash function),这就是使关键字经过散列函数得到一个“随机的地址”,从而减少冲突。 常用的构造散列函数的方法 散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位ǐ 1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a?key + b,其中a和b为常数(这种散列函数叫做自身函数) 2. 数字分析法 3. 平方取中法 4. 折叠法 5. 随机数法 6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。 处理冲突的方法 1. 开放寻址法;Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法: 1. di=1,2,3,…, m-1,称线性探测再散列; 2. di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)称二次探测再散列;

一致性哈希算法应用及优化(最简洁明了的教程)

一致性哈希算法的应用及其优化 一.简单哈希算法 哈希(Hash)就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,使得散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。哈希算法是一种消息摘要算法,虽然哈希算法不是一种加密算法,但由于其单向运算,具有一定的不可逆性使其成为加密算法中的一个重要构成部分。 二.分布式缓存问题 哈希算法除了在数据加密中的运用外,也可以用在常见的数据分布式技术中。哈希计算是通过求模运算来计算哈希值的,然后根据哈希值将数据映射到存储空间中。设有由N 个存储节点组成的存储空间,采用简单哈希计算将一个数据对象object 映射到存储空间上的公式为:Hash(object)% N。 现在假设有一个网站,最近发现随着流量增加,服务器压力越来越大,之前直接读写数据库的方式已经不能满足用户的访问,于是想引入Memcached作为缓存机制。现在一共有三台机器可以作为Memcached服务器,如下图1所示。

图1.三台memcached服务器 可以用简单哈希计算:h = Hash(key) % 3 ,其中Hash是一个从字符串到正整数的哈希映射函数,这样能够保证对相同key的访问会被发送到相同的服务器。现在如果我们将Memcached Server分别编号为0、1、2,那么就可以根据上式和key计算出服务器编号h,然后去访问。 但是,由于这样做只是采用了简单的求模运算,使得简单哈希计算存在很多不足: 1)增删节点时,更新效率低。当系统中存储节点数量发生增加或减少时,映射公式将发生变化为Hash(object)%(N±1),这将使得所有object 的映射位置发生变化,整个系统数据对象的映射位置都需要重新进行计算,系统无法对外界访问进行正常响应,将导致系统处于崩溃状态。 2)平衡性差,未考虑节点性能差异。由于硬件性能的提升,新添加的节点具有更好的承载能力,如何对算法进行改进,使节点性能可以得到较好利用,也是亟待解决的一个问题。 3)单调性不足。衡量数据分布技术的一项重要指标是单调性,单调性是指如果已经有一些内容通过哈希计算分派到了相应的缓冲中,当又有新的缓冲加入到系统中时,哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。 由上述分析可知,简单地采用模运算来计算object 的Hash值的算法显得过于简单,存在节点冲突,且难以满足单调性要求。

单向散列函数算法Hash算法

单向散列函数算法(Hash算法): 一种将任意长度的消息压缩到某一固定长度(消息摘要)的函数(过程不可逆),常见的单向散列算法有MD5,SHA.RIPE-MD,HAVAL,N-Hash 由于Hash函数的为不可逆算法,所以软件智能使用Hash函数作为一个加密的中间步骤 MD5算法: 即为消息摘要算法(Message Digest Algorithm),对输入的任意长度的消息进行预算,产生一个128位的消息摘要 简易过程: 1、数据填充..即填出消息使得其长度与448(mod 512)同余,也就是说长度比512要小64位(为什么数据长度本身已经满足却仍然需要填充?直接填充一个整数倍) 填充方法是附一个1在后面,然后用0来填充.. 2、添加长度..在上述结果之后附加64位的消息长度,使得最终消息的长度正好是512的倍数.. 3、初始化变量..用到4个变量来计算消息长度(即4轮运算),设4个变量分别为A,B,C,D(全部为32位寄存器)A=1234567H,B=89abcdefH,C=fedcba98H,D=7654321H 4、数据处理..首先进行分组,以512位为一个单位,以单位来处理消息.. 首先定义4个辅助函数,以3个32为双字作为输入,输出一个32为双字 F(X,Y,Z)=(X&Y)|((~X)&Z) G(X,Y,Z)=(X&Z)|(Y&(~Z)) H(X,Y,Z)=X^Y^Z I(X,Y,Z)=Y^(X|(~Z)) 其中,^是异或操作 这4轮变换是对进入主循环的512为消息分组的16个32位字分别进行如下操作: (重点)将A,B,C,D的副本a,b,c,d中的3个经F,G,H,I运算后的结果与第四个相加,再加上32位字和一个32位字的加法常数(所用的加法常数由这样一张表T[i]定义,期中i为1至64之中的值,T[i]等于4294967296乘以abs(sin(i))所得结果的整数部分)(什么是加法常数),并将所得之值循环左移若干位(若干位是随机的??),最后将所得结果加上a,b,c,d之一(这个之一也是随机的?)(一轮运算中这个之一是有规律的递增的..如下运算式),并回送至A,B,C,D,由此完成一次循环。(这个循环式对4个变量值进行计算还是对数据进行变换??) For i=0 to N/16 do For j=0 to 15 do Set X[i] to M[i*16+j] End AA = A BB=B CC=C DD=D //第一轮,令[ABCD K S I]表示下面的操作: //A=B+((A+F(B,C,D)+X[K]+T[I])<<

hash算法

Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。 数学表述为:h = H(M) ,其中H( )--单向散列函数,M--任意长度明文,h--固定长度散列值。 在信息安全领域中应用的Hash算法,还需要满足其他关键特性: 第一当然是单向性(one-way),从预映射,能够简单迅速的得到散列值,而在计算上不可能构造一个预映射,使其散列结果等于某个特定的散列值,即构造相应的M=H-1(h)不可行。这样,散列值就能在统计上唯一的表征输入值,因此,密码学上的Hash 又被称为"消息摘要(message digest)",就是要求能方便的将"消息"进行"摘要",但在"摘要"中无法得到比"摘要"本身更多的关于"消息"的信息。 第二是抗冲突性(collision-resistant),即在统计上无法产生2个散列值相同的预映射。给定M,计算上无法找到M',满足H(M)=H(M') ,此谓弱抗冲突性;计算上也难以寻找一对任意的M和M',使满足H(M)=H(M') ,此谓强抗冲突性。要求"强抗冲突性"主要是为了防范所谓"生日攻击(birthday attack)",在一个10人的团体中,你能找到和你生日相同的人的概率是2.4%,而在同一团体中,有2人生日相同的概率是11.7%。类似的,当预映射的空间很大的情况下,算法必须有足够的强度来保证不能轻易找到"相同生日"的人。 第三是映射分布均匀性和差分分布均匀性,散列结果中,为0 的bit 和为 1 的bit ,其总数应该大致相等;输入中一个bit 的变化,散列结果中将有一半以上的bit 改变,这又叫做"雪崩效应(avalanche effect)";要实现使散列结果中出现1bit 的变化,则输入中至少有一半以上的bit 必须发生变化。其实质是必须使输入中每一个bit 的信息,尽量均匀的反映到输出的每一个bit 上去;输出中的每一个bit,都是输入中尽可能多bit 的信息一起作用的结果。 Damgard 和Merkle 定义了所谓"压缩函数(compression function)",就是将一个固定长度输入,变换成较短的固定长度的输出,这对密码学实践上Hash 函数的设计产生了很大的影响。Hash函数就是被设计为基于通过特定压缩函数的不断重复"压缩"输入的分组和前一次压缩处理的结果的过程,直到整个消息都被压缩完毕,最后的输出作为整个消息的散列值。尽管还缺乏严格的证明,但绝大多数业界的研究者都同意,如果压缩函数是安全的,那么以上述形式散列任意长度的消息也将是安全的。这就是所谓Damgard/Merkle 结构: 在下图中,任意长度的消息被分拆成符合压缩函数输入要求的分组,最后一个分组可能需要在末尾添上特定的填充字节,这些分组将被顺序处理,除了第一个消息分组将与散列初始化值一起作为压缩函数的输入外,当前分组将和前一个分组的压缩函数输出一起被作为这一次

属性约简方法概述

属性约简方法概述 属性约简又称维规约或特征选择,从数学的角度考虑,就是有p 维数据 x =(x 1,x 2……x p ),通过某种方法,得到新的数据 x’=(x’1,x’2…… x’k ) , k ≤p , 新的数据在某种评判标准下,最大限度地保留原始数据的特征。属性约简主要是为了解决高维数据计算的复杂性和准确性问题。目标是消除冗余和不相关属性对计算过程和最终结果造成的影响。 对数据进行属性约简的意义,主要从以下几个方面考虑: a) 从机器学习的角度来看,通过属性约简去除噪音属性是非常有意义的; b) 对一些学习算法来说,训练或分类时间随着数据维数的增加而增加,经过属性约简可以降低计算复杂度,减少计算时间; c) 假如不进行属性约简,噪音或不相关属性和期望属性对分类的作用一样,就会对最终结果产生负面影响; d) 当用较多的特征来描述数据时,数据均值表现得更加相似,难以区分。 为了描述属性约简方法,这里假设数据集合为D ,D ={x 1,x 2….x n }, x i 表示D 中第i 个实例,1≤i≤n ,n 为总的实例个数。每个实例包含p 个属性{|x i |=p }。从机器学习的角度来看,属性约简方法可以分为监督的和非监督的两类。下面是几种常用的方法。 (1) PCA 主成分分析 主成分概念是Karl parson 于1901年最先引进。1933年,Hotelling 把它推广到随机变量。主成分分析把高维空间的问题转换到低维空间来处理,有效的降低了计算的复杂度。通过主成分的提取,降低了部分冗余属性的影响,提高了计算的精度。 主成分分析的基本思想为:借助一个正交变换,将分量相关的原随机变量转换成分量不相关的新变量。从代数角度,即将原变量的协方差阵转换成对角阵;从几何角度,将原变量系统变换成新的正交系统,使之指向样本点散布最开的正交方向,进而对多维变量系统进行降维处理[43]。 定义4-1[44]:设12(,,...,)'p X X X X =为p 维随机向量,它的第i 主成分分量可表示'i i Y u X =,i =1,2,…, p 。其中i u 是正交阵U 的第i 列向量。并且满足: 1Y 是12,,...,p X X X 的线性组合中方差最大者; k Y 是与11,...k Y Y -不相关的12,,...,p X X X 的线性组合中方差最大。 (k =2,3,…p )。 定义4-2[45]: 设∑是随机向量12(,,...,)'p X X X X =的协方差矩阵,其特征值-特征向量对1122(,),(,),...(,)p p e e e λλλ,其中12...0p λλλ≥≥≥≥。则第i 个主成分为: 1122 '...i i i i i p p Y e X e X e X e X ==+++ i =1, 2, …p ………………….式

哈 希 常 见 算 法 及 原 理

数据结构与算法-基础算法篇-哈希算法 1. 哈希算法 如何防止数据库中的用户信息被脱库? 你会如何存储用户密码这么重要的数据吗?仅仅 MD5 加密一下存储就够了吗? 在实际开发中,我们应该如何用哈希算法解决问题? 1. 什么是哈希算法? 将任意长度的二进制值串映射成固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值。 2. 如何设计一个优秀的哈希算法? 单向哈希: 从哈希值不能反向推导出哈希值(所以哈希算法也叫单向哈希算法)。 篡改无效: 对输入敏感,哪怕原始数据只修改一个Bit,最后得到的哈希值也大不相同。 散列冲突: 散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小。 执行效率: 哈希算法的执行效率要尽量高效,针对较长的文本,也能快速计算哈

希值。 2. 哈希算法的常见应用有哪些? 7个常见应用:安全加密、唯一标识、数据校验、散列函数、负载均衡、数据分片、分布式存储。 1. 安全加密 常用于加密的哈希算法: MD5:MD5 Message-Digest Algorithm,MD5消息摘要算法 SHA:Secure Hash Algorithm,安全散列算法 DES:Data Encryption Standard,数据加密标准 AES:Advanced Encryption Standard,高级加密标准 对用于加密的哈希算法,有两点格外重要,第一点是很难根据哈希值反向推导出原始数据,第二点是散列冲突的概率要小。 在实际开发中要权衡破解难度和计算时间来决定究竟使用哪种加密算法。 2. 唯一标识 通过哈希算法计算出数据的唯一标识,从而用于高效检索数据。 3. 数据校验 利用哈希算法对输入数据敏感的特点,可以对数据取哈希值,从而高效校验数据是否被篡改过。 4. 散列函数 1.如何防止数据库中的用户信息被脱库?你会如何存储用户密码这么重要的数据吗?

哈希算法介绍

哈希算法介绍 LG GROUP system office room 【LGA16H-LGYY-LGUA8Q8-LGA162】

哈希算法简介

目录 1哈希算法概念 ...................................................... 2哈希函数 .......................................................... 3冲突的解决方法 .................................................... 4哈希算法应用 ......................................................

关键词: 算法、哈希、c语言 摘要: 哈希算法在软件开发和Linux内核中多次被使用,由此可以见哈希算法的实用性和重要性。本文介绍了哈希算法的原理和应用,并给出了简略的代码实现,以便读者理解。

1哈希算法概念 哈希(hash 散列,音译为哈希)算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。 哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希算法都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。 哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上,并以关键字在地址区间中的项作为记录在表中的存储位置,这种表称为哈希表,所得存储位置称为哈希地址。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。 查找一般是对项的摸个部分(及数据成员)进行,这部分称为键(key)。例如,项可以由字符串作为键,附带一些数据成员。 理想的哈希表数据结构只不过是一个包含一些项的具有固定大小的数组。 通常的习惯是让项从0到 TableSize-1之间变化。 将每个键映射到0到TableSize-1 这个范围中的某个 数,并且将其放到适当的单元中,这个映射就称为散列函数 (hash funciton)。 如右图,john被散列到3,phil被散列到4,dave 被散列 到6,mary被散列到7. 这是哈希的基本思想。剩下的问题则是要选择一个函数, 决定当两个键散列到同一个值的时候(称为冲突),应该做 什么。

哈 希 常 见 算 法 及 原 理

计算与数据结构篇 - 哈希算法 (Hash) 计算与数据结构篇 - 哈希算法 (Hash) 哈希算法的定义和原理非常简单,基本上一句话就可以概括了。将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值。 构成哈希算法的条件: 从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法)对输入数据非常敏感,哪怕原始数据只修改了一个 Bit,最后得到的哈希值也大不相同; 散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小; 哈希算法的执行效率要尽量高效,针对较长的文本,也能快速地计算出哈希值。 哈希算法的应用(上篇) 安全加密 说到哈希算法的应用,最先想到的应该就是安全加密。最常用于加密的哈希算法是 MD5(MD5 Message-Digest Algorithm,MD5 消息摘要算法)和 SHA(Secure Hash Algorithm,安全散列算法)。 除了这两个之外,当然还有很多其他加密算法,比如 DES(Data Encryption Standard,数据加密标准)、AES(Advanced Encryption Standard,高级加密标准)。

前面我讲到的哈希算法四点要求,对用于加密的哈希算法来说,有两点格外重要。第一点是很难根据哈希值反向推导出原始数据,第二点是散列冲突的概率要很小。 不过,即便哈希算法存在散列冲突的情况,但是因为哈希值的范围很大,冲突的概率极低,所以相对来说还是很难破解的。像 MD5,有 2^128 个不同的哈希值,这个数据已经是一个天文数字了,所以散列冲突的概率要小于 1-2^128。 如果我们拿到一个 MD5 哈希值,希望通过毫无规律的穷举的方法,找到跟这个 MD5 值相同的另一个数据,那耗费的时间应该是个天文数字。所以,即便哈希算法存在冲突,但是在有限的时间和资-源下,哈希算法还是被很难破解的。 对于加密知识点的补充,md5这个算法固然安全可靠,但网络上也有针对MD5中出现的彩虹表,最常见的思路是在密码后面添加一组盐码(salt), 比如可以使用md5(1234567.'2019@STARK-%$#-idje-789'),2019@STARK-%$#-idje-789 作为盐码起到了一定的保护和安全的作用。 唯一标识(uuid) 我们可以给每一个图片取一个唯一标识,或者说信息摘要。比如,我们可以从图片的二进制码串开头取 100 个字节,从中间取 100 个字节,从最后再取 100 个字节,然后将这 300 个字节放到一块,通过哈希算法(比如 MD5),得到一个哈希字符串,用它作为图片的唯一标识。通过这个唯一标识来判定图片是否在图库中,这样就可以减少很多工作量。

哈 希 常 见 算 法 及 原 理 ( 2 0 2 0 )

哈希算法乱谈(摘自知乎) 最近【现场实战追-女孩教-学】初步了解了Hash算法的相关知识,一些人的见解让我能够迅速的了解相对不熟悉的知识,故想摘录下来,【QQ】供以后温故而知新。 HASH【⒈】算法是密码学的基础,比较常用的有MD5和SHA,最重要的两【О】条性质,就是不可逆和无冲突。 所谓不【1】可逆,就是当你知道x的HASH值,无法求出x; 所谓无【б】冲突,就是当你知道x,无法求出一个y,使x与y的HA【9】SH值相同。 这两条性【⒌】质在数学上都是不成立的。因为一个函数必然可逆,且【2】由于HASH函数的值域有限,理论上会有无穷多个不同的原始值【6】,它们的hash值都相同。MD5和SHA做到的,是求逆和求冲突在计算上不可能,也就是正向计算很容易,而反向计算即使穷尽人类所有的计算资-源都做不到。 顺便说一下,王小云教授曾经成功制造出MD5的碰撞,即md5(a) = md5(b)。这样的碰撞只能随机生成,并不能根据一个已知的a求出b(即并没有破坏MD5的无冲突特性)。但这已经让他声名大噪了。 HASH算法的另外一个很广泛的用途,就是很多程序员都会使用的在数据库中保存用户密码的算法,通常不会直接保存用户密码(这样DBA就能看到用户密码啦,好危险啊),而是保存密码的HASH值,验

证的时候,用相同的HASH函数计算用户输入的密码得到计算HASH值然后比对数据库中存储的HASH值是否一致,从而完成验证。由于用户的密码的一样的可能性是很高的,防止DBA猜测用户密码,我们还会用一种俗称“撒盐”的过程,就是计算密码的HASH值之前,把密码和另外一个会比较发散的数据拼接,通常我们会用用户创建时间的毫秒部分。这样计算的HASH值不大会都是一样的,会很发散。最后,作为一个老程序员,我会把用户的HASH值保存好,然后把我自己密码的HASH值保存到数据库里面,然后用我自己的密码和其他用户的用户名去登录,然后再改回来解决我看不到用户密码而又要“偷窥”用户的需要。最大的好处是,数据库泄露后,得到用户数据库的黑客看着一大堆HASH值会翻白眼。 哈希算法又称为摘要算法,它可以将任意数据通过一个函数转换成长度固定的数据串(通常用16进制的字符串表示),函数与数据串之间形成一一映射的关系。 举个粒子,我写了一篇小说,摘要是一个string:'关于甲状腺精灵的奇妙冒险',并附上这篇文章的摘要是'2d73d4f15c0db7f5ecb321b6a65e5d6d'。如果有人篡改了我的文章,并发表为'关于JOJO的奇妙冒险',我可以立即发现我的文章被篡改过,因为根据'关于JOJO的奇妙冒险'计算出的摘要不同于原始文章的摘要。 可见,摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡

字符串哈希算法

经典字符串Hash函数 工作中经常需要用大hash这个强有力的工具,hash表最核心的部分则在于怎么设计一个好的hash函数,以使数据更均匀地分布在若干个桶上。下面来介绍一下我现在用到的一个hash函数,我们来看代码: unsigned chostcachehash::get_host_key(const string& host) { int result = 1; unsigned i = 0; for (i = 0; i > 24); h = h ^ g; } } return h; } openssl中出现的字符串hash函数 unsigned long lh_strhash(char *str) { int i,l; unsigned long ret=0; unsigned short *s;

属性约简方法概述

属性约简方法概述 Document number:NOCG-YUNOO-BUYTT-UU986-1986UT

属性约简方法概述 属性约简又称维规约或特征选择,从数学的角度考虑,就是有p 维数据 x =(x 1,x 2……x p ),通过某种方法,得到新的数据 x’=(x’1,x’2…… x’k ) , k ≤p , 新的数据在某种评判标准下,最大限度地保留原始数据的特征。属性约简主要是为了解决高维数据计算的复杂性和准确性问题。目标是消除冗余和不相关属性对计算过程和最终结果造成的影响。 对数据进行属性约简的意义,主要从以下几个方面考虑: a) 从机器学习的角度来看,通过属性约简去除噪音属性是非常有意义的; b) 对一些学习算法来说,训练或分类时间随着数据维数的增加而增加,经过属性约简可以降低计算复杂度,减少计算时间; c) 假如不进行属性约简,噪音或不相关属性和期望属性对分类的作用一样,就会对最终结果产生负面影响; d) 当用较多的特征来描述数据时,数据均值表现得更加相似,难以区分。 为了描述属性约简方法,这里假设数据集合为D ,D ={x 1,x 2….x n }, x i 表示D 中第i 个实例,1≤i≤n ,n 为总的实例个数。每个实例包含p 个属性{|x i |=p }。从机器学习的角度来看,属性约简方法可以分为监督的和非监督的两类。下面是几种常用的方法。 (1) PCA 主成分分析 主成分概念是Karl parson 于1901年最先引进。1933年,Hotelling 把它推广到随机变量。主成分分析把高维空间的问题转换到低维空间来处理,有效的降低了计算的复杂度。通过主成分的提取,降低了部分冗余属性的影响,提高了计算的精度。 主成分分析的基本思想为:借助一个正交变换,将分量相关的原随机变量转换成分量不相关的新变量。从代数角度,即将原变量的协方差阵转换成对角阵;从几何角度,将原变量系统变换成新的正交系统,使之指向样本点散布最开的正交方向,进而对多维变量系统进行降维处理[43]。 定义4-1[44]:设12(,,...,)'p X X X X =为p 维随机向量,它的第i 主成分分量可表示'i i Y u X =,i =1,2,…, p 。其中i u 是正交阵U 的第i 列向量。并且满足: 1Y 是12,,...,p X X X 的线性组合中方差最大者; k Y 是与11,...k Y Y -不相关的12,,...,p X X X 的线性组合中方差最大。(k =2, 3,…p )。

哈希算法介绍

哈希算法简介

目录 1哈希算法概念 (2) 2哈希函数 (3) 3冲突的解决方法 (3) 4哈希算法应用 (4)

关键词: 算法、哈希、c语言 摘要: 哈希算法在软件开发和Linux内核中多次被使用,由此可以见哈希算法的实用性和重要性。本文介绍了哈希算法的原理和应用,并给出了简略的代码实现,以便读者理解。

1哈希算法概念 哈希(hash 散列,音译为哈希) 算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。 哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希算法都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。 哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上,并以关键字在地址区间中的项作为记录在表中的存储位置,这种表称为哈希表,所得存储位置称为哈希地址。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。 查找一般是对项的摸个部分(及数据成员)进行,这部分称为键(key )。例如,项可以由字符串作为键,附带一些数据成员。 理想的哈希表数据结构只不过是一个包含一些项的具有固定大小的数组。 通常的习惯是让项从0到 TableSize-1之间变化。 将每个键映射到0到TableSize-1 这个范围中的某个数 ,并且将其放到适当的单元中,这个映射就称为散列函数(hash funciton )。 如右图,john 被散列到3,phil 被散列到4,dave 被散列到6,mary 被散列到7. 这是哈希的基本思想。剩下的问题则是要选择一个函数,决定当两个键散列到同一个值的时候(称为冲突),应该做什么。

几种字符串哈希HASH算法的性能比较

几种字符串哈希HASH算法的性能比较 2011年01月26日星期三 19:40 这不就是要找hash table的hash function吗? 1 概述 链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但Hash链表查找的时间效率为O(1)。 设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的算法无法比拟的,Hash 链表的构造和冲突的不同实现方法对效率当然有一定的影响,然而Hash函数是Hash链表最核心的部分,本文尝试分析一些经典软件中使用到的字符串 Hash函数在执行效率、离散性、空间利用率等方面的性能问题。 2 经典字符串Hash函数介绍 作者阅读过大量经典软件原代码,下面分别介绍几个经典软件中出现的字符串Hash函数。 2.1 PHP中出现的字符串Hash函数 static unsigned long hashpjw(char *arKey, unsigned int nKeyLength) { unsigned long h = 0, g; char *arEnd=arKey+nKeyLength; while (arKey < arEnd) { h = (h << 4) + *arKey++; if ((g = (h & 0xF0000000))) { h = h ^ (g >> 24); h = h ^ g; } } return h; } 2.2 OpenSSL中出现的字符串Hash函数 unsigned long lh_strhash(char *str) { int i,l; unsigned long ret=0; unsigned short *s; if (str == NULL) return(0); l=(strlen(str)+1)/2; s=(unsigned short *)str; for (i=0; i ret^=(s[i]<<(i&0x0f)); return(ret);

SHA-1(安全哈希算法实现)

SHA-1(安全哈希算法实现) 如题,不知道sha-1的自己百度吧。 1 #include 2 #include //定义vector数组 3 #include //记录消息 4usingnamespace std; 5 6constint NUM = 8; //一个字由32比特(或者8个16进制数) 7constint BIT = 512; //消息认证码要以512比特一组 8 9//字常量 10string H0 = "67452301"; 11string H1 = "EFCDAB89"; 12string H2 = "98BADCFE"; 13string H3 = "10325476"; 14string H4 = "C3D2E1F0"; 15 16//定义SHA1(安全哈希算法)类 17class SHA1 18 { 19public: 20//将一个字符串形式的字转化为vector数组 21 vector hex_into_dec(string word); 22 23//将vector转化为string字符串形式 24string num_into_message(vector A); 25 26//两个字X和Y的逻辑"和" 27 vector word_AND(vector A,vector B); 28 29//两个字X和Y的逻辑"或" 30 vector word_OR(vector A,vector B); 31 32//两个字X和Y的逻辑"异或" 33 vector word_XOR(vector A,vector B); 34 35//两个字X和Y的逻辑"补" 36 vector word_COMPLEMENT(vector A); 37 38//两个字X和Y的摸2^32整数加 39 vector word_ADD(vector A,vector B); 40

常见的Hash算法

常见的Hash算法 1.简介 哈希函数按照定义可以实现一个伪随机数生成器(PRNG),从这个角度可以得到一个公认的结论:哈希函数之间性能的比较可以通过比较其在伪随机生成方面的比较来衡量。 一些常用的分析技术,例如泊松分布可用于分析不同的哈希函数对不同的数据的碰撞率(collision rate)。一般来说,对任意一类的数据存在一个理论上完美的哈希函数。这个完美的哈希函数定义是没有发生任何碰撞,这意味着没有出现重复的散列值。在现实中它很难找到一个完美的哈希散列函数,而且这种完美函数的趋近变种在实际应用中的作用是相当有限的。在实践中人们普遍认识到,一个完美哈希函数的哈希函数,就是在一个特定的数据集上产生的的碰撞最少哈希的函数。 现在的问题是有各种类型的数据,有一些是高度随机的,有一些有包含高纬度的图形结构,这些都使得找到一个通用的哈希函数变得十分困难,即使是某一特定类型的数据,找到一个比较好的哈希函数也不是意见容易的事。我们所能做的就是通过试错方法来找到满足我们要求的哈希函数。可以从下面两个角度来选择哈希函数: 1.数据分布 一个衡量的措施是考虑一个哈希函数是否能将一组数据的哈希值进行很好的分布。要进行这种分析,需要知道碰撞的哈希值的个数,如果用链表来处理碰撞,则可以分析链表的平均长度,也可以分析散列值的分组数目。 2.哈希函数的效率 另个一个衡量的标准是哈希函数得到哈希值的效率。通常,包含哈希函数的算法的算法复杂度都假设为O(1),这就是为什么在哈希表中搜索数据的时间复杂度会被认为是"平均为O(1)的复杂度",而在另外一些常用的数据结构,比如图(通常被实现为红黑树),则被认为是O(logn)的复杂度。 一个好的哈希函数必修在理论上非常的快、稳定并且是可确定的。通常哈希函数不可能达到O(1)的复杂度,但是哈希函数在字符串哈希的线性的搜索中确实是非常快的,并且通常哈希函数的对象是较小的主键标识符,这样整个过程应该是非常快的,并且在某种程度上是稳定的。 在这篇文章中介绍的哈希函数被称为简单的哈希函数。它们通常用于散列(哈希字符串)数据。它们被用来产生一种在诸如哈希表的关联容器使用的key。这些哈希函数不是密码安全的,很容易通过颠倒和组合不同数据的方式产生完全相同的哈希值。 2.哈希方法学 哈希函数通常是由他们产生哈希值的方法来定义的,有两种主要的方法: 1.基于加法和乘法的散列 这种方式是通过遍历数据中的元素然后每次对某个初始值进行加操作,其中加的值和这个数据的一个元素相关。通常这对某个元素值的计算要乘以一个素数。

常用的哈希函数

常用的哈希函数 通用的哈希函数库有下面这些混合了加法和一位操作的字符串哈希算法。下面的这些算法在用法和功能方面各有不同,但是都可以作为学习哈希算法的实现的例子。(其他版本代码实现见下载) 1.RS 从Robert Sedgwicks的Algorithms in C一书中得到了。我(原文作者)已经添加了一些简单的优化的算法,以加快其散列过程。 [java]view plaincopy 1.public long RSHash(String str) 2. { 3.int b = 378551; 4.int a = 63689; 5.long hash = 0; 6.for(int i = 0; i < str.length(); i++) 7. { 8. hash = hash * a + str.charAt(i); 9. a = a * b; 10. } 11.return hash; 12. } 2.JS Justin Sobel写的一个位操作的哈希函数。 [c-sharp]view plaincopy 1.public long JSHash(String str) 2. { 3.long hash = 1315423911; 4.for(int i = 0; i < str.length(); i++) 5. { 6. hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2)); 7. } 8.return hash; 9. } 3.PJW 该散列算法是基于贝尔实验室的彼得J温伯格的的研究。在Compilers一书中(原则,技术和工具),建议采用这个算法的散列函数的哈希方法。

【免费下载】hash算法实验

实验课程名称:电子商务安全管理实验项目名称1:DES 、RSA 和Hash 算法的实现实验成绩 试验者 王秀梅专业班级1105441 组别同组者无实验的目的 (1) 掌握常用加密处理软件的使用方法。 (2) 理解DES 、RSA 和Hash 算法的原理。 (3) 了解MD5算法的破解方法。实验环境 (1) 装有Windows XP/2003操作系统的PC 机1台。 (2) MixedCS 、RSATool 、DAMN_HashCalc 、MD5Crack 工具软件各1套。实验步骤1、请参考实验指导PPT 。并在最后写实验心得体会。2、将实验电子版提交FTP——1105441电子商务安全管理——第一次实验报告,文件名为“学号(1105441)+姓名+实验一”。 实验过程记录 (1) 对称加密算法DES 的实现 步骤1:双击运行MixedCS.exe 程序,打开的程序主界面步骤2:单击“浏览文件”按钮,选择要进行DES 加密的源文件,选择完成后在“输出文件”文本框中会自动出现默认的加密后的文件名。步骤3:选中“DES 加密”单选按钮,在“DES 密钥”文本框中输入5个字符 (区分大小、管路敷设技术通过管线敷设技术,不仅可以解决吊顶层配置不规范问题,而且可保障各类管路习题到位。在管路敷设过程中,要加强看护关于管路高中资料试卷连接管口处理高中资料试卷弯扁度固定盒位置保护层防腐跨接地线弯曲半径标高等,要求技术交底。管线敷设技术中包含线槽、管架等多项方式,为解决高中语文电气课件中管壁薄、接口不严等问题,合理利用管线敷设技术。线缆敷设原则:在分线盒处,当不同电压回路交叉时,应采用金属隔板进行隔开处理;同一线槽内,强电回路须同时切断习题电源,线缆敷设完毕,要进行检查和检测处理。、电气课件中调试对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料试卷相互作用与相互关系,根据生产工艺高中资料试卷要求,对电气设备进行空载与带负荷下高中资料试卷调控试验;对设备进行调整使其在正常工况下与过度工作下都可以正常工作;对于继电保护进行整核对定值,审核与校对图纸,编写复杂设备与装置高中资料试卷调试方案,编写重要设备高中资料试卷试验方案以及系统启动方案;对整套启动过程中高中资料试卷电气设备进行调试工作并且进行过关运行高中资料试卷技术指导。对于调试过程中高中资料试卷技术问题,作为调试人员,需要在事前掌握图纸资料、设备制造厂家出具高中资料试卷试验报告与相关技术资料,并且了解现场设备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。 、电气设备调试高中资料试卷技术电力保护装置调试技术,电力保护高中资料试卷配置技术是指机组在进行继电保护高中资料试卷总体配置时,需要在最大限度内来确保机组高中资料试卷安全,并且尽可能地缩小故障高中资料试卷破坏范围,或者对某些异常高中资料试卷工况进行自动处理,尤其要避免错误高中资料试卷保护装置动作,并且拒绝动作,来避免不必要高中资料试卷突然停机。因此,电力高中资料试卷保护装置调试技术,要求电力保护装置做到准确灵活。对于差动保护装置高中资料试卷调试技术是指发电机一变压器组在发生内部故障时,需要进行外部电源高中资料试卷切除从而采用高中资料试卷主要保护装置。

哈 希 常 见 算 法 及 原 理

Python算法系列-哈希算法 哈希算法一、常见数据查找算法简介二、什么是哈希三、实例:两个数字的和1.问题描述2.双指针办法解决3.哈希算法求解四、总结哈希算法又称散列函数算法,是一种查找算法。就是把一些复杂的数据通过某种映射关系。映射成更容易查找的方式,但这种映射关系可能会发生多个关键字映射到同一地址的现象,我们称之为冲突。在这种情况下,我们需要对关键字进行二次或更多次处理。出这种情况外,哈希算法可以实现在常数时间内存储和查找这些关键字。 一、常见数据查找算法简介 常见的数据查找算法: 顺序查找:是最简单的查找方法。需要对数据集中的逐个匹配。所以效率相对较低,不太适合大量数据的查找问题。 二分法查找:效率很高,但是要求数据必须有序。面对数据排序通常需要更多的时间。 深度优先和广度优先算法:对于大量的数据查找问题,效率并不高。这个我们后面专门讲解。 阿希查找算法:查找速度快,查询插入,删除操作简单等原因获得广泛的应用。 二、什么是哈希 哈希查找的原理:根据数量预先设一个长度为M的数组。使用一个哈希函数F并以数据的关键字作为自变量得到唯一的返回值,返回值的范围

是0~M-1。这样就可以利用哈希函数F将数据元素映射到一个数组的某一位下标,并把数据存放在对应位置,查找时利用哈希函数F计算,该数据应存放在哪里,在相应的存储位置取出查找的数据。 这里就有一个问题: 关键字的取值在一个很大的范围,数据在通过哈希函数进行映射时。很难找到一个哈希函数,使得这些关键字都能映射到唯一的值。就会出现多个关键字映射到同一个值的现象,这种现象我们称之为冲突。 哈西算法冲突的解决方案有很多:链地址法,二次再散列法。线性探测再散列建立一个公共溢出区 注意:链地址法本质是数组+链表的数据结构 链地址法存储数据过程: 首先建立一个数组哈希存储所有链表的头指针。由数组的关键字key 通过对应的哈希函数计算出哈希地址。找到相应的桶号之后,建立新的节点存储该数据。并把节点放到桶内的链表的最后面或者最前面。 链地址法查找数据:由数据关键字通过哈希。函数计算关键字对应的哈希地址之后顺序比较同类不节点。是否与所查到的关键字一样,直到找到数据为止,如果全部节点都不和关键字一样,则书名哈系表里没有该数据。解决了哈希函数的冲突。 用链地址法构造的散列表插入和删除节点操作易于实现,所以构造链表的时间开销很低。但是指针需要开辟额外的地址空间,当数据量很大时会扩大哈希表规模,内存空间要求较大。 三、实例:两个数字的和

相关文档
相关文档 最新文档