几种经典的HASH算法的实现(源代码)
哈希查找算法的源代码 c语言

哈希查找算法的源代码 c语言【问题描述】针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
[基本要求]假设人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构照,用链表法处理冲突。
[测试数据]读取熟悉的30个人的姓名。
#include <fstream>#include <iostream>#include <cmath>using namespace std;#define Maxsize 57struct record{ char name[20];char tel[20];char add[20];};typedef record * precord;struct HashTable{ int elem[Maxsize]; //存放数组a[]的下标int count;};typedef HashTable * pHashTable;int Number; //统计当前数组a[]中的记录总数void Getdata(precord a) //从文件telphone.txt中读取数据存放到数组a[] { Number=0;ifstream infile("telphone.txt",ios::in|ios::binary);if(!infile) {cout<<"文件打开失败!\n"; exit(1);}while(!infile.eof() && infile.get()!=EOF) //文件不为空并且文件指针没有指到结束符{infile.seekg(Number*sizeof(a[Number]),ios::beg); //定位文件指针infile.read((char *)&a[Number],sizeof(a[Number]));Number++;}infile.close();}void Add(precord a) //添加记录{ int i,num;cout<<"当前文件内已有"<<Number<<"条记录\n";cout<<"请输入添加的个数:";cin>>num;ofstream ofile("telphone.txt",ios::app);if(! ofile) {cout<<"文件打开失败!"; exit(1);}for(i=0;i<num;i++){ cout<<"请输入第"<<Number+1<<"个人的姓名"<<endl; cin>>a[Number].name;cout<<"请输入第"<<Number+1<<"个人的电话"<<endl; cin>>a[Number].tel;cout<<"请输入第"<<Number+1<<"个人的地址"<<endl; cin>>a[Number].add;ofile.seekp(ios::end);ofile.write((char *)&a[Number],sizeof(a[Number])); Number++;}ofile.close();}void Print(precord a) //显示所有记录{ int i;for(i=0;i<Number;i++){cout<<"第"<<i+1<<"个人的信息为:\n";cout<<" 姓名:"<<a[i].name<<endl;cout<<" 电话:"<<a[i].tel<<endl;cout<<" 地址:"<<a[i].add<<endl;}}int Hash(char str[]) //除留取余{ long val=0;char p[20],*p1;strcpy(p,str);p1=p;while(*p1!='\0')val=val+*p1++; //将字符串中的所有字符对应的ASCII值相加return(val%Maxsize);}int derter; //线性增量int Line_Sollution(int address) //采用线性探测解决冲突{derter++;if(derter==Maxsize) return(-1);else return((address+derter)%Maxsize);}int n;int Square_Sollution(int address) //采用平方探测法解决冲突{ int j;derter++;if(derter==Maxsize) return -1;n=n*(-1);j=(int(pow(derter,2))*n+address)%Maxsize;return(j);}void Init_Hash(pHashTable h) //初始化哈希表{ int i;for(i=0;i<Maxsize;i++)h->elem[i]=-1;}int menu;void Creathash_Name(pHashTable h,precord a)//以用户名为关键字创建哈希表{ cout<<"--------------------------------------------------------------------------------\n";cout<<" 1----以线性探测建表\n";cout<<" 2----以平方探测建表\n";cout<<"--------------------------------------------------------------------------------\n";int i,address;cin>>menu;Init_Hash(h);for(i=0;i<Number;i++){ derter=0;n=-1;address=Hash(a[i].name);while(h->elem[address]!=-1){if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);if(address==-1) break;}if(address!=-1) { h->elem[address]=i; h->count++;}}cout<<"姓名哈希表已成功建立!\n";}void Search_Name(pHashTable h,precord a) //查找并显示指定姓名的记录{ cout<<"请输入要查找的姓名:";char nam[20];int address,i=1;cin>>nam;address=Hash(nam);derter=0;n=-1;while(h->elem[address]!=-1 && strcmp(nam,a[h->elem[address]].name)!=0) { if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);i++;if(address==-1) break;}if(h->elem[address]!=-1 && strcmp(nam,a[h->elem[address]].name)==0) { cout<<"你要查找的信息为:\n";cout<<" 姓名:"<<a[h->elem[address]].name<<endl;cout<<" 电话:"<<a[h->elem[address]].tel<<endl;cout<<" 地址:"<<a[h->elem[address]].add<<endl;cout<<"比较次数为"<<i<<endl;}else cout<<"无此姓名,查找失败!";}void Creathash_tel(pHashTable h,precord a)//以电话号为关键字创建哈希表{ cout<<"--------------------------------------------------------------------------------\n";cout<<" 1----以线性探测建表\n";cout<<" 2----以平方探测建表\n";cout<<"--------------------------------------------------------------------------------\n";int i,address;cin>>menu;Init_Hash(h);for(i=0;i<Number;i++){ derter=0;n=-1;address=Hash(a[i].tel);while(h->elem[address]!=-1){if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);if(address==-1) break;}if(address!=-1) { h->elem[address]=i; h->count++;}}cout<<"电话号哈希表已成功建立!\n";}void Search_tel(pHashTable h,precord a)//查找并显示指定电话号的记录{ cout<<"请输入要查找的电话:";char telphone[20];int address,i=1; //i统计比较次数cin>>telphone;address=Hash(telphone);derter=0; n=-1; //初始化线性增量while(h->elem[address]!=-1 && strcmp(telphone,a[h->elem[address]].tel)!=0){ if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);i++;if(address==-1) break;}if(h->elem[address]!=-1 && strcmp(telphone,a[h->elem[address]].tel)==0) { cout<<"你要查找的信息为:\n";cout<<" 姓名:"<<a[h->elem[address]].name<<endl;cout<<" 电话:"<<a[h->elem[address]].tel<<endl;cout<<" 地址:"<<a[h->elem[address]].add<<endl;cout<<"比较次数为"<<i<<endl;}else cout<<"无此电话,查找失败!";}void Menu() //功能菜单函数{for(int i=1;i<=5;i++)cout<<endl;cout<<" 电话号码查询系统\n";cout<<'\n';cout<<" ★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆\n";cout<<" ☆ 0-------退出★\n";cout<<" ★ 1-------添加☆\n";cout<<" ☆ 2-------显示所有★\n";cout<<" ★ 3-------以性命建立哈希表☆\n";cout<<" ☆ 4-------以电话建立哈希表★\n";cout<<" ★ 5-------按用户名查找☆\n";cout<<" ☆ 6-------按电话号查找★\n";cout<<" ☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★\n"; cout<<" 使用说明:\n";cout<<" 1.添加新纪录后,如要进行查找请先进行3或4操作\n";cout<<" 2.按用户名查找之前,请先进行3操作建立用户名哈希表\n";cout<<" 3.按用户名查找之前,请先进行4操作建立电话号哈希表\n";}void exit(){int i;for(i=1;i<=4;i++)cout<<endl;cout<<" ◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◇◆◇\n"; cout<<" ◆ ◆\n";cout<<" ◇ 电话号码查询系统◇\n";cout<<" ◆ ◆\n";cout<<" ◇ 谢谢您的使用! ◇\n";cout<<" ◆ ◆\n";cout<<"◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇\n";}int main(){ record a[Maxsize];pHashTable H=new HashTable;Getdata(a); //将文件中的数据读入到数组a中start:Menu();int menu1;cin>>menu1;switch(menu1){ case 0:system("cls");exit();break;case 1:Add(a);system("pause");system("cls");goto start;break;case 2:Print(a);system("pause");system("cls");goto start;break;case 3:Creathash_Name(H,a);system("pause");system("cls");goto start;break;case 4:Creathash_tel(H,a);system("pause");system("cls");goto start;break;case 5:Search_Name(H,a);system("pause");system("cls");goto start;break;case 6:Search_tel(H,a);system("pause");system("cls");goto start;break;default:cout<<"请输入正确的操作选项!\n";system("cls");goto start;break;} return 0; }。
hash原理和实现方式

Hash原理和实现方式1. 介绍Hash(哈希)是一种将任意长度的输入数据转换为固定长度输出的算法。
该算法通过将输入数据映射到一个固定大小的哈希值来实现。
哈希函数通常用于数据完整性校验、密码学以及数据索引等领域。
本文将详细解释Hash的基本原理和实现方式,并介绍一些常见的Hash算法。
2. Hash函数基本原理Hash函数是Hash算法的核心组成部分,它接受任意长度的输入数据,并生成一个固定长度的哈希值。
2.1 确定性Hash函数应该是确定性的,即对于相同的输入数据,始终生成相同的哈希值。
这样可以保证在相同条件下产生相同结果,便于验证和比较。
2.2 均匀性理想情况下,Hash函数应该能够将不同的输入数据均匀地映射到不同的哈希值上。
这样可以最大程度地避免冲突,提高哈希表等数据结构的效率。
2.3 不可逆性Hash函数应该是不可逆的,即从哈希值无法推导出原始输入数据。
这样可以保护敏感信息和密码等重要数据的安全。
2.4 固定长度Hash函数应该生成固定长度的哈希值,无论输入数据的长度如何。
这样可以方便存储和比较哈希值。
3. Hash算法实现方式Hash算法有多种实现方式,下面介绍几种常见的实现方式。
3.1 分组Hash算法分组Hash算法将输入数据分成多个固定大小的块,然后对每个块进行处理,并生成最终的哈希值。
3.1.1 MD5(Message Digest Algorithm 5)MD5是一种广泛使用的分组Hash算法,它接受任意长度的输入数据,并生成一个128位(16字节)的哈希值。
MD5主要用于数据完整性校验和密码存储等领域。
然而,由于其安全性较低和易受到碰撞攻击,已经不再推荐使用。
3.1.2 SHA-1(Secure Hash Algorithm 1)SHA-1是一种与MD5类似的分组Hash算法,它接受任意长度的输入数据,并生成一个160位(20字节)的哈希值。
SHA-1在密码学领域中仍然广泛使用,但也存在安全性问题。
Python中的Hash函数实现方式

Python中的Hash函数实现方式1.概述Hash函数是计算机科学中十分重要的一个概念,在Python语言中,Hash函数被广泛使用,Python标准库中也包含了一些常用的Hash函数。
本文将从以下几个方面对Python中的Hash函数进行介绍:Hash函数的概念、Hash函数的应用、Hash函数的实现方式以及Hash函数的应用实例等。
2. Hash函数的概念Hash函数,也叫散列函数,是将任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换为固定长度的输出(又叫做散列值,Hash值,message digest)的函数。
Hash函数的特点是输入和输出的类型不一定相同,而且无论输入的数据多少,输出的结果长度是固定的。
Hash函数的设计是为了保证输入数据的机密性、数据完整性以及防止重放攻击等。
在Python中,Hash函数是一个内置函数,它被用于创建Hash对象,Hash函数的格式如下:hash(object)其中,object表示要计算Hash值的对象,可以是数字、字符串、元组、列表、字典等。
3. Hash函数的应用Hash函数在计算机科学中有很多应用,下面简单介绍几个常见的应用:3.1哈希表哈希表是一种数据结构,它通过Hash函数将关键字映射为索引,可以实现快速的数据检索,常见的哈希表有字典(Dictionary)、集合(Set),Python中的字典和集合就是基于哈希表实现的,因为Hash函数可以将输入的键(Key)映射为索引(Hash值),并将索引与值(Value)组合存储在相应的数据结构中。
在Python中,字典和集合是非常常见的数据结构,它们在实际开发中被广泛使用。
3.2文件完整性验证Hash函数还可以被用于文件完整性验证,比如,我们可以通过计算文件内容的Hash值来判断文件是否被篡改或者被恶意软件所感染,这对于保证文件的安全性具有重要作用。
3.3数字签名数字签名是一种用于确认在不可否认的情况下,数据的来源和完整性的技术。
hash原理和实现方式

hash原理和实现方式Hash原理是一种将数据映射到固定长度的唯一标识的算法。
它的基本原理是将输入数据通过哈希函数进行计算,生成固定长度的哈希值作为输出。
哈希函数具有以下特点:1.唯一性:对于任何不同的输入,哈希函数都应该生成不同的哈希值。
2.高效性:哈希函数计算速度应该尽可能快,将输入数据转换为哈希值的过程应该是高效的。
3.一致性:当输入数据不变时,哈希值也不应该变化。
4.不可逆性:根据哈希值不能反推出原始数据。
5.均匀性:哈希函数应该能够将不同大小的输入数据映射到固定长度的哈希值上,且均匀分布。
实现方式有多种,下面介绍常见的几种实现方式:1. 散列链表(Hash Table with Linked Lists):散列链表是一种简单的哈希实现方式。
它使用数组作为存储数据的主要数据结构,当发生哈希冲突时,使用链表来存储冲突的元素。
每个元素通过哈希函数计算出一个索引值,然后被插入到该索引对应的链表中。
这种实现方式的优点是易于实现,但是当哈希冲突较多时,效率会降低。
2. 开放定址法(Open Addressing):开放定址法是另一种哈希实现方式,它不使用链表来存储冲突的元素,而是将冲突的元素直接放在数组中的其他位置。
当发生哈希冲突时,继续寻找数组中的下一个空槽位,直到找到一个空槽位或者遍历整个数组。
这种实现方式的优点是无需额外的链表结构,可以提高存储密度和查询效率。
但是,如果哈希表已满,插入新元素的时间复杂度可能会增加。
3. 拉链法(Chaining):拉链法是一种解决哈希冲突的方法,它在每个哈希表槽位上维护一个链表。
当发生哈希冲突时,将冲突的元素放入对应的链表中。
这种实现方式的优点是可以处理大量的哈希冲突,并且不需要额外的空间。
缺点是需要维护额外的链表结构,查询效率可能会降低。
4. 一致性哈希(Consistent Hashing):一致性哈希是一种用于分布式系统中的哈希实现方式。
它通过在哈希空间中使用虚拟节点,将哈希空间映射到环形空间上。
常见的hash算法及其原理

常见的hash算法及其原理一、引言在计算机科学中,哈希算法(也称为散列函数)是一种将数据映射到固定大小值的算法。
它的目的是将数据压缩成固定长度的散列值,并且能够快速且高效地检索和比较数据。
本文将介绍几种常见的哈希算法及其原理。
二、MD5算法MD5(Message Digest Algorithm 5)是一种广泛使用的哈希算法,它将任意长度的数据映射为128位的散列值。
MD5算法的原理如下:1. 数据分块:将待哈希的数据划分为固定大小的块,每个块通常为512位。
2. 填充数据:如果最后一个块的长度小于512位,则需要填充数据,确保每个块都是512位。
3. 初始化状态:初始化MD5算法的状态,包括四个32位的寄存器A、B、C、D。
4. 压缩函数:对每个块进行处理,通过一系列的操作将块的数据与当前状态的寄存器进行混合。
5. 输出结果:将最终的状态值A、B、C、D连接起来,即为MD5算法的散列值。
MD5算法具有较快的计算速度和较低的冲突概率,但由于其存在一定的安全性问题,如碰撞攻击等,在一些领域已经被更安全的算法所取代。
三、SHA-1算法SHA-1(Secure Hash Algorithm 1)是一种常用的哈希算法,它将任意长度的数据映射为160位的散列值。
SHA-1算法的原理如下:1. 数据填充:与MD5算法类似,对数据进行填充以确保每个块的长度为512位。
2. 初始化状态:初始化SHA-1算法的状态,包括五个32位的寄存器A、B、C、D、E。
3. 压缩函数:对每个块进行处理,通过一系列的操作将块的数据与当前状态的寄存器进行混合。
4. 输出结果:将最终的状态值A、B、C、D、E连接起来,即为SHA-1算法的散列值。
SHA-1算法相对于MD5算法来说,具有更高的安全性,但在一些安全性要求更高的场景下,也存在一定的风险,因此在一些领域也被更安全的算法所取代。
四、SHA-256算法SHA-256是SHA-2(Secure Hash Algorithm 2)系列中最常用的算法之一,它将任意长度的数据映射为256位的散列值。
c语言哈希算法实例

c语言哈希算法实例摘要:一、哈希算法概述二、C 语言哈希算法实例1.哈希函数的定义2.哈希表的构建3.哈希表的应用示例三、总结正文:一、哈希算法概述哈希算法(Hash Algorithm)是一种将不同长度的输入数据转化为固定长度输出的算法,通常用于快速查找、数据完整性校验等场合。
哈希算法具有快速、高效的特点,其主要思想是将输入数据经过一定的变换后得到一个哈希值,该值可以用来表示原始数据。
二、C 语言哈希算法实例1.哈希函数的定义在C 语言中,我们可以自定义一个哈希函数,用于将输入字符串转化为哈希值。
以下是一个简单的哈希函数示例:```c#include <stdio.h>#include <string.h>unsigned int hash(char *str) {unsigned int hash_val = 5381;int c;while ((c = *str++))hash_val = ((hash_val << 5) + hash_val) + c; /* hash_val = hash_val * 33 + c */return hash_val;}```2.哈希表的构建哈希表是一种基于数组实现的数据结构,它可以将哈希值与原始数据关联起来。
以下是一个简单的哈希表构建示例:```c#include <stdio.h>#include <string.h>#include <stdlib.h>#define HASH_SIZE 100struct Node {char key[50];int value;struct Node *next;};struct HashTable {struct Node *table[HASH_SIZE];};struct HashTable *createHashTable() {struct HashTable *hashTable = (struct HashTable*)malloc(sizeof(struct HashTable));for (int i = 0; i < HASH_SIZE; i++) {hashTable->table[i] = NULL;}return hashTable;}```3.哈希表的应用示例以下是一个简单的哈希表应用示例,用于实现字符串的快速查找:```c#include <stdio.h>#include <string.h>#include <stdlib.h>#define HASH_SIZE 100struct Node {char key[50];int value;struct Node *next;struct HashTable {struct Node *table[HASH_SIZE];};struct HashTable *createHashTable() {struct HashTable *hashTable = (struct HashTable*)malloc(sizeof(struct HashTable));for (int i = 0; i < HASH_SIZE; i++) {hashTable->table[i] = NULL;}return hashTable;}int searchHashTable(struct HashTable *hashTable, char *str) { int index = hash(str) % HASH_SIZE;struct Node *current = hashTable->table[index];while (current!= NULL) {if (strcmp(current->key, str) == 0) {return current->value;}current = current->next;}return -1;int main() {struct HashTable *hashTable = createHashTable();char str[] = "hello";int value = searchHashTable(hashTable, str);if (value == -1) {printf("String not found.");} else {printf("String found, value: %d", value);}return 0;}```三、总结本示例通过自定义哈希函数和构建哈希表,实现了字符串的快速查找。
哈希表及其常用算法(代码实例)

哈希表及其常⽤算法(代码实例)<hash表的特性>Hash 表是使⽤ O(1) 时间进⾏数据的插⼊删除和查找,但是 hash 表不保证表中数据的有序性,这样在 hash 表中查找最或者最⼩数据的时间是 O(N) 。
<寻址和 hash 函数>理想状态下 hash ⾜够⼤,每⼀数据保存在⼀个 hash 存储单元内,这样对于插⼊删除和查找某⼀个数据就可以直接得到。
但是现实情况下 hash 表不可能⽆限⼤,⽽且理论上保存的数据的个数是没有限制的,这样保存的数据的数量就远远⼤于 hash 表的存储单元的数量。
为了实现在 O(1) 内对数据进⾏插⼊删除和查找,就必须将⼀个数据映射到 hash 表中的固定位置,这个映射函数就是 hash 函数。
Hash 函数通过对数据进⾏计算得到⼀个在 hash 表中的位置地址。
图 1.1 理想的 hash 表要选择较好的 hash 函数,以及 hash 表存储单元的数量,这样才能使保存在 hash 表中的数据均匀分布。
理想状态不太可能实现,由于存储的数据数量远远⼤于 hash 表存储单元的数量,所以再好的 hash 函数也可能使不同的数据得到相同的映射位置,这就造成了冲突。
但是好的 hash 函数可以将这种冲突降到最低。
<分离链接>解决这种冲突的第⼀种⽅法是借助链表来实现,就是将数据实际存放在与 hash 表存储单元相链接的链表中,⽽不是 hash 的存储单元中。
图 2.1 分离链表当产⽣冲突的时候,将两个数据都链接在同⼀ hash 存储单元保存的链表中。
当⼀个存储单元保存的链表中有多个数据的时候,对于链表后⾯的数据的查找添加和删除就是不是严格意义上的 O(1) 了。
⼀个好的 hash 函数可以使得这个链表很短。
最坏情况下,当所有的数据都保存在⼀个 hash 单元指定的链表中的时候,那么这个 hash 就和链表⼀样了。
<开放地址>使⽤开放地址⽅法解决冲突的时候,数据仍然保存在 hash 表的存储单元中,但是当冲突发⽣的时候,要再次计算新的地址。
字符串Hash函数(源代码)

字符串Hash函数今天根据自己的理解重新整理了一下几个字符串hash函数,使用了模板,使其支持宽字符串,代码如下:/// @brief BKDR Hash Function/// @detail 本算法由于在Brian Kernighan与Dennis Ritchie的《The C Programming Language》一书被展示而得名,是一种简单快捷的hash算法,也是Java目前采用的字符串的Hash算法(累乘因子为31)。
template<class T>size_t BKDRHash(const T *str){register size_t hash = 0;while (size_t ch = (size_t)*str++){hash = hash * 131 + ch; // 也可以乘以31、131、1313、13131、131313..// 有人说将乘法分解为位运算及加减法可以提高效率,如将上式表达为:hash = hash << 7 + hash << 1 + hash + ch;// 但其实在Intel平台上,CPU内部对二者的处理效率都是差不多的,// 我分别进行了100亿次的上述两种运算,发现二者时间差距基本为0(如果是Debug版,分解成位运算后的耗时还要高1/3);// 在ARM这类RISC系统上没有测试过,由于ARM内部使用Booth's Algorithm 来模拟32位整数乘法运算,它的效率与乘数有关:// 当乘数8-31位都为1或0时,需要1个时钟周期// 当乘数16-31位都为1或0时,需要2个时钟周期// 当乘数24-31位都为1或0时,需要3个时钟周期// 否则,需要4个时钟周期// 因此,虽然我没有实际测试,但是我依然认为二者效率上差别不大}return hash;}/// @brief SDBM Hash Function/// @detail 本算法是由于在开源项目SDBM(一种简单的数据库引擎)中被应用而得名,它与BKDRHash思想一致,只是种子不同而已。
五元组hash算法python代码

一、概述在计算机科学中,哈希算法是一种将输入数据转换为固定大小值的算法。
它被广泛应用于密码学、数据完整性验证和数据检索等领域。
而五元组hash算法是一种特定的哈希算法,其将数据以五个元素的形式进行哈希处理。
二、五元组hash算法原理五元组hash算法的原理是将数据以五个元素的形式表示,然后将这五个元素作为输入进行哈希计算,得到一个固定大小的哈希值。
这个哈希值可以用作数据的唯一标识符,也可以用来确保数据的完整性和一致性。
在五元组hash算法中,通常使用的五个元素包括源IP位置区域、目标IP位置区域、源端口号、目标端口号和协议类型。
这五个元素能够完整地描述一次网络通信的会话信息,因此非常适合用来进行哈希计算。
三、五元组hash算法Python代码实现下面是一个简单的五元组hash算法的Python代码实现:```pythonimport hashlibdef five_tuple_hash(source_ip, destination_ip, source_port, destination_port, protocol):data = source_ip + destination_ip + str(source_port) +str(destination_port) + protocolhash_value = hashlib.sha256(data.encode()).hexdigest()return hash_value```在这段代码中,我们首先使用了Python内置的hashlib库,然后定义了一个名为five_tuple_hash的函数。
这个函数接收源IP位置区域、目标IP位置区域、源端口号、目标端口号和协议类型等五个参数作为输入。
我们将这五个参数拼接成一个字符串,并使用SHA-256哈希算法对这个字符串进行哈希计算。
我们返回了计算得到的哈希值作为函数的返回值。
四、五元组hash算法Python代码的使用以下是一个简单的示例,展示了如何使用上述的五元组hash算法Python代码:```pythonsource_ip = '192.168.1.1'destination_ip = '192.168.1.2'source_port = xxxdestination_port = 80protocol = 'TCP'hash_value = five_tuple_hash(source_ip, destination_ip, source_port, destination_port, protocol)print(f"The hash value for the given five-tuple is: {hash_value}") ```在这个示例中,我们先设置了源IP位置区域、目标IP位置区域、源端口号、目标端口号和协议类型等五个参数的取值,然后调用了five_tuple_hash函数来计算这个五元组的哈希值。
常见的hash算法有哪些及其原理是什么

常见的hash算法有哪些及其原理是什么Hash,一般翻译做散列,也有直接音译为哈希的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。
这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址。
作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。
通过将单向数学函数(有时称为哈希算法)应用到任意数量的数据所得到的固定大小的结果。
如果输入数据中有变化,则哈希也会发生变化。
哈希可用于许多操作,包括身份验证和数字签名。
也称为消息摘要。
简单解释:哈希(Hash)算法,即散列函数。
它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。
同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。
哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。
常用hash算法的介绍:(1)MD4MD4(RFC 1320)是MIT 的Ronald L. Rivest在1990 年设计的,MD 是Message Digest (消息摘要)的缩写。
它适用在32位字长的处理器上用高速软件实现它是基于32位操作数的位操作来实现的。
(2)MD5MD5(RFC 1321)是Rivest 于1991年对MD4的改进版本。
它对输入仍以512位分组,其输出是4个32位字的级联,与MD4 相同。
MD5比MD4来得复杂,并且速度较之要。
Hash算法(含python实现)

Hash算法(含python实现)Hash算法的原理是将任意长度的数据映射为固定长度的散列值。
这个映射过程是单向的,不可逆的。
即给定一个散列值,无法逆推出原始数据。
同时,即使原始数据只改变了一个比特的值,生成的散列值也会有很大的差异,这被称为“雪崩效应”。
Python有多种内置的Hash算法。
下面介绍三种常见的Hash算法及其在Python中的实现。
1. MD5(Message Digest Algorithm 5)MD5是一种常用的Hash算法,它将输入数据转换为128位(16字节)的散列值。
MD5算法的实现可以通过Python的`hashlib`库来实现。
```pythonimport hashlibdef md5(data):m = hashlib.md5( # 创建MD5对象m.update(data.encode("utf-8")) # 更新数据return m.hexdigest( # 返回散列值data = "Hello, world!"hash_value = md5(data)print("MD5:", hash_value)```2. SHA-1(Secure Hash Algorithm 1)SHA-1是一种安全性较高的Hash算法,它将输入数据转换为160位(20字节)的散列值。
SHA-1算法的实现也可以通过Python的`hashlib`库来实现。
```pythonimport hashlibdef sha1(data):m = hashlib.sha1( # 创建SHA-1对象m.update(data.encode("utf-8")) # 更新数据return m.hexdigest( # 返回散列值data = "Hello, world!"hash_value = sha1(data)print("SHA-1:", hash_value)```3. SHA-256(Secure Hash Algorithm 256-bit)SHA-256是SHA-2系列中最常用的Hash算法,它将输入数据转换为256位(32字节)的散列值。
Hash算法(含python实现)

Hash算法(含python实现)1. 简介哈希(hash)也翻译作散列。
Hash算法,是将⼀个不定长的输⼊,通过散列函数变换成⼀个定长的输出,即散列值。
这种散列变换是⼀种单向运算,具有不可逆性即不能根据散列值还原出输⼊信息,因此严格意义上讲Hash算法是⼀种消息摘要算法,不是⼀种加密算法。
常见的hash算法有:SM3、MD5、SHA-1等。
2. 应⽤Hash主要应⽤在数据结构以及密码学领域。
在不同的应⽤场景下,hash函数的选择也会有所侧重。
⽐如在管理数据结构时,主要要考虑运算的快速性,并且要保证hash均匀分布;⽽应⽤在密码学中就要优先考虑抗碰撞性,避免出现两段不同明⽂hash值相同的情况发⽣。
2.1 在密码学领域的应⽤在密码学中,Hash算法的作⽤主要是⽤于消息摘要和签名,换句话说,它主要⽤于对整个消息的完整性进⾏校验。
⽐如⼀些登陆⽹站并不会直接明⽂存储⽤户密码,存储的是经过hash处理的密码的摘要(hash值),当⽤户登录时只需要对⽐输⼊明⽂的摘要与数据库存储的摘要是否相同;即使⿊客⼊侵或者维护⼈员访问数据库也⽆法获取⽤户的密码明⽂,⼤⼤提⾼了安全性。
2.2 在数据结构中的应⽤使⽤Hash算法的数据结构叫做哈希表,也叫散列表,主要是为了提⾼查询的效率。
它通过把关键码值映射到表中⼀个位置来访问记录,以加快查找的速度。
这个映射函数就是hash函数,存放记录的数组叫做哈希表。
在数据结构中应⽤时,有时需要较⾼的运算速度⽽弱化考虑抗碰撞性,可以使⽤⾃⼰构建的哈希函数。
3. Hash算法的python实现3.1 ⾃定义哈希函数⾃定义哈希函数通常可利⽤除留余数、移位、循环哈希、平⽅取中等⽅法。
下⾯这个例⼦就是我⾃⼰定义的⼀个哈希函数,运⽤了取模运算和异或运算。
# coding:utf-8# ⾃定义哈希函数def my_hash(x):return (x % 7) ^ 2print(my_hash(1)) # 输出结果:3print(my_hash(2)) # 输出结果:0print(my_hash(3)) # 输出结果:1print(my_hash(4)) # 输出结果:63.2 hash()函数在python中有内置的哈希函数hash(),返回⼀个对象(数字、字符串,不能直接⽤于 list、set、dictionary)的哈希值。
java的hash算法

java的hash算法Java中的哈希算法主要用于哈希表等数据结构,以快速查找元素。
哈希算法的主要目标是尽可能均匀地分布数据,以便在插入、删除和查找操作中获得更好的性能。
在Java中,哈希算法通常由``、``、``等类实现。
这些类内部都使用了一个散列函数(即哈希函数),用于将键转换为哈希码,这个码就是键在哈希表中的位置。
下面是一个简单的哈希函数的例子:```javapublic int hash(String key) {int hash = 0;for (int i = 0; i < (); i++) {hash = 31 hash + (i);}return hash;}```在这个例子中,我们用了一个非常简单的哈希函数,它将字符串的每个字符乘以一个常数(在这个例子中是31),然后求和。
这种简单的哈希函数在实际的哈希表中可能不会工作得很好,因为不同的键可能会得到相同的哈希码。
因此,更复杂的哈希函数可能会使用一些额外的技术,如使用多个散列函数或者处理冲突(当两个键的哈希码相同时)。
此外,Java还提供了一些内建的哈希算法,例如MD5和SHA系列,用于生成数据的哈希值。
这些算法主要用于密码学和数据完整性检查。
例如,可以使用Java的MessageDigest类来生成MD5哈希:```javaimport ;import ;import ;public class Main {public static void main(String[] args) {try {MessageDigest md = ("MD5");("hello world".getBytes(_8));byte[] digest = ();(bytesToHex(digest)); // 输出:b814767d28a6b5fb39f14e6a301756c4} catch (NoSuchAlgorithmException e) {();}}private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder();for (byte b : bytes) {(("%02x", b));}return ();}}```。
java 常用的hash方法

Java常用的hash方法在Java编程中,hash方法是一种常见的数据处理技术,它将输入数据转换为固定长度的哈希值。
哈希函数将任意长度的数据映射到固定长度的哈希值,这个过程是非常快速且高效的。
在Java中,我们可以使用多种不同的哈希函数来满足不同的需求。
哈希算法简介哈希算法是一种将任意长度数据映射到固定长度值的算法。
它具有以下特点:•输入数据可以是任意长度。
•输出结果是固定长度的哈希值。
•相同输入一定会得到相同输出。
•不同输入得到相同输出的概率非常低。
哈希算法被广泛应用于密码学、数据完整性校验和查找等领域。
在Java中,我们通常使用java.security.MessageDigest类来实现各种哈希函数。
常用的Java哈希方法1. MD5MD5(Message Digest Algorithm 5)是一种广泛使用的哈希函数,它产生一个128位(16字节)长的哈希值。
MD5算法具有以下特点:•高度可靠:对于不同输入产生相同输出(冲突)概率非常低。
•快速计算:MD5算法的计算速度非常快。
在Java中,我们可以使用以下代码获取字符串的MD5哈希值:import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5Example {public static void main(String[] args) {String input = "Hello, World!";try {MessageDigest md = MessageDigest.getInstance("MD5");byte[] hashBytes = md.digest(input.getBytes());StringBuilder sb = new StringBuilder();for (byte b : hashBytes) {sb.append(String.format("%02x", b));}String hashValue = sb.toString();System.out.println("MD5 Hash Value: " + hashValue);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}}2. SHA-1SHA-1(Secure Hash Algorithm 1)是一种广泛使用的哈希函数,它产生一个160位(20字节)长的哈希值。
java的哈希算法

java的哈希算法Java中常用的哈希算法有MD5、SHA-1、SHA-256等。
这些算法都可以使用Java标准库中的MessageDigest类来实现。
下面是使用MD5算法对字符串进行哈希的示例代码:```import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class HashExample {public static void main(String[] args) {String input = "Hello World";String md5Hash = hashString(input, "MD5");System.out.println("MD5 Hash: " + md5Hash);}public static String hashString(String input, String algorithm) { try {MessageDigest messageDigest =MessageDigest.getInstance(algorithm);byte[] hashedBytes =messageDigest.digest(input.getBytes());StringBuilder stringBuilder = new StringBuilder();for (byte b : hashedBytes) {stringBuilder.append(String.format("%02x", b));}return stringBuilder.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}}```这个示例代码中的`hashString`方法接受两个参数:待哈希的字符串和算法名称。
几种经典的Hash算法的实现(源代码)

链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但Hash链表查找的时间效率为O(1)。
设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的算法无法比拟的,Hash链表的构造和冲突的不同实现方法对效率当然有一定的影响,然而Hash函数是Hash链表最核心的部分,下面是几款经典软件中使用到的字符串Hash函数实现,通过阅读这些代码,我们可以在Hash算法的执行效率、离散性、空间利用率等方面有比较深刻的了解。
下面分别介绍几个经典软件中出现的字符串Hash函数。
●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;}●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; iret^=(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);}●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@) and* Glenn Fowler (gsf@). Landon Curt Noll (chongo@) * 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);}#endifMysql中对字符串Hash函数还区分了大小写●另一个经典字符串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; }。
关于Hash的几种常用算法

关于Hash的⼏种常⽤算法1 RSHash1/* 【算法】RSHash(因Robert Sedgwicks在其《Algorithms in C》⼀书中展⽰⽽得名)2 * 【说明】63689和378551都是质数,之所以取这两个数,我想是因为抗碰撞⼩(散列分布均匀)3 * 【时间】祁俊辉->2017.5.174 * */5public class RSHash {6//RSHash算法7static long RS_Hash(String str){8int a=63689;9int b=378551;10long hash=0;11for(int i=0;i<str.length();i++){12 hash=hash*a+str.charAt(i);13//System.out.println(hash);14 a=a*b;15//System.out.println(a);16 }17return (hash & 0x7FFFFFFF);//32位18//return (hash & 0x7FFFFFFFFFFFFFFFL);//64位19 }20//主函数21public static void main(String[] args) {22 System.out.println(Long.toBinaryString(RS_Hash("祁俊辉")));23 }24 }2 BKDRHash1/* 【算法】BKDRHash(Java字符串类的Hash算法,累成因⼦取31)2 * 【说明】累成因⼦可以为31/131/1313/13131/131313...3 * 【时间】祁俊辉->2017.5.174 * */5public class BKDRHash {6//BKDRHash算法7static long BKDR_Hash(String str){8long seed=131;9long hash=0;10for(int i=0;i<str.length();i++){11 hash=hash*seed+str.charAt(i);12//System.out.println(hash);13 }14return (hash & 0x7FFFFFFF);//32位15//return (hash & 0x7FFFFFFFFFFFFFFFL);//64位16 }17//主函数18public static void main(String[] args) {19 System.out.println(Long.toBinaryString(BKDR_Hash("祁俊辉")));20 }21 }3 DJBHash1/* 【算法】DJBHash(⽬前公布最有效的Hash算法)2 * 【说明】俗称"Times33"算法3 * 【时间】祁俊辉->2017.5.174 * */5public class DJBHash {6//DJBHash算法7static long DJB_Hash(String str){8long hash=5381;9for(int i=0;i<str.length();i++){10 hash=((hash<<5)+hash)+str.charAt(i);11//System.out.println(hash);12 }13return (hash & 0x7FFFFFFF);//32位14//return (hash & 0x7FFFFFFFFFFFFFFFL);//64位15 }16//主函数17public static void main(String[] args) {18 System.out.println(Long.toBinaryString(DJB_Hash("祁俊辉")));19 }20 }4 JSHash1/* 【算法】JSHash(由Justin Sobel发明的⼀种hash算法)2 * 【说明】位操作3 * 【时间】祁俊辉->2017.5.184 * */5public class JSHash {6//JSHash算法7static long JS_Hash(String str){8long hash=1315423911;9for(int i=0;i<str.length();i++){10 hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));11//System.out.println(hash);12 }13return (hash & 0x7FFFFFFF);//32位14//return (hash & 0x7FFFFFFFFFFFFFFFL);//64位15 }16//主函数17public static void main(String[] args) {18 System.out.println(Long.toBinaryString(JS_Hash("祁俊辉")));19 }20 }5 SDBMHash1/* 【算法】SDBMHash2 * 【说明】与BKDRHash思想⼀致,只是数乘因⼦不同3 * 【时间】祁俊辉->2017.5.184 * */5public class SDBMHash {6//SDBMHash算法7static long SDBM_Hash(String str){8long hash=0;9for(int i=0;i<str.length();i++){10 hash=hash*65599+str.charAt(i);11//hash=str.charAt(i)+(hash<<6)+(hash<<16)-hash;12//System.out.println(hash);13 }14return (hash & 0x7FFFFFFF);//32位15//return (hash & 0x7FFFFFFFFFFFFFFFL);//64位16 }17//主函数18public static void main(String[] args) {19 System.out.println(Long.toBinaryString(SDBM_Hash("祁俊辉")));20 }21 }。
hash的实现方式

hash的实现方式Hash的实现方式Hash(哈希)是一种将数据映射到固定长度的唯一值的算法,常用于数据加密、数据校验和数据索引等场景。
在计算机科学中,Hash 算法有多种实现方式,每种实现方式都有自己的特点和适用场景。
本文将介绍几种常见的Hash实现方式。
一、散列函数散列函数是Hash算法的基础,它将任意长度的输入(也称为消息)映射到固定长度的输出(也称为散列值或Hash值)。
散列函数应满足以下几个特点:1. 输入不同,输出一定不同。
2. 输入相同,输出一定相同。
3. 输入发生变化,输出也会发生变化。
常见的散列函数有MD5、SHA-1、SHA-256等。
这些散列函数在信息安全领域被广泛应用,用于验证文件完整性、密码存储等场景。
二、分离链接法分离链接法是一种解决散列冲突(即不同的输入映射到相同的散列值)的方法。
它将Hash表中的每个槽(slot)关联一个链表,当发生冲突时,将新的元素添加到链表的末尾。
分离链接法的优点是简单易实现,能够处理任意数量的冲突。
然而,它的查找效率较低,需要遍历整个链表才能找到目标元素。
三、开放定址法开放定址法是另一种解决散列冲突的方法。
它通过探测(probing)来寻找可用的槽。
具体的探测方式包括线性探测、二次探测和双重散列。
1. 线性探测:当发生冲突时,依次检查下一个槽,直到找到一个空槽或者遍历完整个Hash表。
2. 二次探测:当发生冲突时,通过二次探测函数计算下一个槽的位置,直到找到一个空槽或者遍历完整个Hash表。
3. 双重散列:当发生冲突时,通过另一个散列函数计算下一个槽的位置,直到找到一个空槽或者遍历完整个Hash表。
开放定址法的优点是内存占用较小,查找效率较高。
然而,它对冲突的处理方式相对较为简单,可能导致聚集现象(即冲突的元素倾向于聚集在一起),进而影响查找效率。
四、完全散列完全散列是一种解决散列冲突的方法,它通过建立两层Hash表来实现。
首先,使用第一层Hash函数将输入映射到第一层Hash表中的槽;然后,对于每个槽,使用第二层Hash函数将冲突的元素映射到该槽的链表中。
Hash算法大全(java实现)

Hash算法大全(java实现)[java] view plaincopy/*** Hash算法大全<br>* 推荐使用FNV1算法* @algorithm None* @author Goodzzp 2006-11-20* @lastEdit Goodzzp 2006-11-20* @editDetail Create*/public class HashAlgorithms{/*** 加法hash* @param key 字符串* @param prime 一个质数* @return hash结果*/public static int additiveHash(String key, int prime){int hash, i;for (hash = key.length(), i = 0; i < key.length(); i++)hash += key.charAt(i);return (hash % prime);}/*** 旋转hash* @param key 输入字符串* @param prime 质数* @return hash值*/public static int rotatingHash(String key, int prime){int hash, i;for (hash=key.length(), i=0; i<key.length(); ++i)hash = (hash<<4)^(hash>>28)^key.charAt(i);return (hash % prime);// return (hash ^ (hash>>10) ^ (hash>>20));}// 替代:// 使用:hash = (hash ^ (hash>>10) ^ (hash>>20)) & mask; // 替代:hash %= prime;/*** MASK值,随便找一个值,最好是质数*/static int M_MASK = 0x8765fed1;/*** 一次一个hash* @param key 输入字符串* @return 输出hash值*/public static int oneByOneHash(String key){int hash, i;for (hash=0, i=0; i<key.length(); ++i){hash += key.charAt(i);hash += (hash << 10);hash ^= (hash >> 6);}hash += (hash << 3);hash ^= (hash >> 11);hash += (hash << 15);// return (hash & M_MASK);return hash;}/*** Bernstein's hash* @param key 输入字节数组* @param level 初始hash常量* @return 结果hash*/public static int bernstein(String key){int hash = 0;int i;for (i=0; i<key.length(); ++i) hash = 33*hash + key.charAt(i);return hash;}////// Pearson's Hash// char pearson(char[]key, ub4 len, char tab[256])// {// char hash;// ub4 i;// for (hash=len, i=0; i<len; ++i)// hash=tab[hash^key[i]];// return (hash);// }//// CRC Hashing,计算crc,具体代码见其他// ub4 crc(char *key, ub4 len, ub4 mask, ub4 tab[256]) // {// ub4 hash, i;// for (hash=len, i=0; i<len; ++i)// hash = (hash >> 8) ^ tab[(hash & 0xff) ^ key[i]]; // return (hash & mask);// }/*** Universal Hashing*/public static int universal(char[]key, int mask, int[] tab) {int hash = key.length, i, len = key.length;for (i=0; i<(len<<3); i+=8){char k = key[i>>3];if ((k&0x01) == 0) hash ^= tab[i+0];if ((k&0x02) == 0) hash ^= tab[i+1];if ((k&0x04) == 0) hash ^= tab[i+2];if ((k&0x08) == 0) hash ^= tab[i+3];if ((k&0x10) == 0) hash ^= tab[i+4];if ((k&0x20) == 0) hash ^= tab[i+5];if ((k&0x40) == 0) hash ^= tab[i+6];if ((k&0x80) == 0) hash ^= tab[i+7];}return (hash & mask);}/*** Zobrist Hashing*/public static int zobrist( char[] key,int mask, int[][] tab) {int hash, i;for (hash=key.length, i=0; i<key.length; ++i)hash ^= tab[i][key[i]];return (hash & mask);}// LOOKUP3// 见Bob Jenkins(3).c文件// 32位FNV算法static int M_SHIFT = 0;/*** 32位的FNV算法* @param data 数组* @return int值*/public static int FNVHash(byte[] data){int hash = (int)2166136261L;for(byte b : data)hash = (hash * 16777619) ^ b;if (M_SHIFT == 0)return hash;return (hash ^ (hash >> M_SHIFT)) & M_MASK;}/*** 改进的32位FNV算法1* @param data 数组* @return int值*/public static int FNVHash1(byte[] data){final int p = 16777619;int hash = (int)2166136261L;for(byte b:data)hash = (hash ^ b) * p;hash += hash << 13;hash ^= hash >> 7;hash += hash << 3;hash ^= hash >> 17;hash += hash << 5;return hash;}/*** 改进的32位FNV算法1* @param data 字符串* @return int值*/public static int FNVHash1(String data) {final int p = 16777619;int hash = (int)2166136261L;for(int i=0;i<data.length();i++)hash = (hash ^ data.charAt(i)) * p;hash += hash << 13;hash ^= hash >> 7;hash += hash << 3;hash ^= hash >> 17;hash += hash << 5;return hash;}/*** Thomas Wang的算法,整数hash*/public static int intHash(int key){key += ~(key << 15);key ^= (key >>> 10);key += (key << 3);key ^= (key >>> 6);key += ~(key << 11);key ^= (key >>> 16);return key;}/*** RS算法hash* @param str 字符串*/public static int RSHash(String str){int b = 378551;int a = 63689;int hash = 0;for(int i = 0; i < str.length(); i++){hash = hash * a + str.charAt(i);a = a * b;}return (hash & 0x7FFFFFFF);}/* End Of RS Hash Function *//*** JS算法*/public static int JSHash(String str){int hash = 1315423911;for(int i = 0; i < str.length(); i++){hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));}return (hash & 0x7FFFFFFF);}/* End Of JS Hash Function *//*** PJW算法*/public static int PJWHash(String str){int BitsInUnsignedInt = 32;int ThreeQuarters = (BitsInUnsignedInt * 3) / 4;int OneEighth = BitsInUnsignedInt / 8;int HighBits = 0xFFFFFFFF << (BitsInUnsignedInt - OneEighth);int hash = 0;int test = 0;for(int i = 0; i < str.length();i++){hash = (hash << OneEighth) + str.charAt(i);if((test = hash & HighBits) != 0){hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));}}return (hash & 0x7FFFFFFF);}/* End Of P. J. Weinberger Hash Function *//*** ELF算法*/public static int ELFHash(String str){int hash = 0;int x = 0;for(int i = 0; i < str.length(); i++){hash = (hash << 4) + str.charAt(i);if((x = (int)(hash & 0xF0000000L)) != 0){hash ^= (x >> 24);hash &= ~x;}}return (hash & 0x7FFFFFFF);}/* End Of ELF Hash Function *//*** BKDR算法*/public static int BKDRHash(String str){int seed = 131; // 31 131 1313 13131 131313 etc..int hash = 0;for(int i = 0; i < str.length(); i++){hash = (hash * seed) + str.charAt(i);}return (hash & 0x7FFFFFFF);}/* End Of BKDR Hash Function *//*** SDBM算法*/public static int SDBMHash(String str){int hash = 0;for(int i = 0; i < str.length(); i++){hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;}return (hash & 0x7FFFFFFF);}/* End Of SDBM Hash Function *//*** DJB算法*/public static int DJBHash(String str){int hash = 5381;for(int i = 0; i < str.length(); i++){hash = ((hash << 5) + hash) + str.charAt(i);}return (hash & 0x7FFFFFFF);}/* End Of DJB Hash Function *//*** DEK算法*/public static int DEKHash(String str){int hash = str.length();for(int i = 0; i < str.length(); i++){hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);}return (hash & 0x7FFFFFFF);}/* End Of DEK Hash Function *//*** AP算法*/public static int APHash(String str){int hash = 0;for(int i = 0; i < str.length(); i++){hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ str.charAt(i) ^ (hash >> 3)) :(~((hash << 11) ^ str.charAt(i) ^ (hash >> 5)));}// return (hash & 0x7FFFFFFF);return hash;}/* End Of AP Hash Function *//*** JA V A自己带的算法*/public static int java(String str){int h = 0;int off = 0;int len = str.length();for (int i = 0; i < len; i++){h = 31 * h + str.charAt(off++);}return h;}/*** 混合hash算法,输出64位的值*/public static long mixHash(String str){long hash = str.hashCode();hash <<= 32;hash |= FNVHash1(str);return hash;}}Hash算法有很多很多种类。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
return h;
}
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++; }
●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; } ●OpenSSL 中出现的字符串 Hash 函数 unsigned long lh_strhash(char *str) { int i,l; unsigned long ret=0; unsigned short *s;
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;
return((ret>>16)^ret); } ●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;
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;
for (hash = 0; key < end; key++) { hash *= 16777619; hash ^= (uint) (uchar) toupper(*key); }
return (hash); } #endif
MHash 函数 unsigned int hash(char *str) { register unsigned int h; register unsigned char *p;
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@) and * Glenn Fowler (gsf@). Landon Curt Noll (chongo@) * 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;
链表查找的时间效率为 O(N),二分法为 log2N,B+ Tree 为 log2N,但 Hash 链表查找的时间效率为 O(1)。 设计高效算法往往需要使用 Hash 链表,常数级的查找速度是任何别的算法无法比拟的,Hash 链表的构造和 冲突的不同实现方法对效率当然有一定的影响,然 而 Hash 函数是 Hash 链表最核心的部分,下面是几款经 典软件中使用到的字符串 Hash 函数实现,通过阅读这些代码,我们可以在 Hash 算法的执行效率、离散性、 空间利用率等方面有比较深刻的了解。 下面分别介绍几个经典软件中出现的字符串 Hash 函数。