哈希
1:哈希算法概述:
哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。哈希(Hash)算法,即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。
简单些来说:hash函数常常用在加密学,这是因为使用hash函数可以产生一个“指纹”,发送者发送数据时带有这个指纹,接收通过计算可以判断这个指纹是否是正确的,即也可以判断数据传送是否完整,数据一旦在传输中途被破坏,那么这个指纹也就不正确了。
2:特点:
由上面的概述可以得出 哈希函数具有 完整性 压缩性 抗修改性 容易计算 安全性
3:内容:
class GeneralHashFunctionLibrary {/*RSHash*/ public long RSHash(String str) { int b = 378551; int a = 63689; long hash = 0; for(int i = 0; i < str.length(); i++) { hash = hash * a + str.charAt(i); a = a * b; } return hash; } /*JSHash*/ public long JSHash(String str) { long hash = 1315423911; for(int i = 0; i < str.length(); i++) hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2)); return hash; } /*PJWHash*/ public long PJWHash(String str) { long BitsInUnsignedInt = (long)(4 * 8); long ThreeQuarters = (long)((BitsInUnsignedInt * 3) / 4); long OneEighth = (long)(BitsInUnsignedInt / 8); long HighBits = (long)(0xFFFFFFFF)<<(BitsInUnsignedInt-OneEighth); long hash = 0; long 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; } /*ELFHash*/ public long ELFHash(String str) { long hash = 0; long x = 0; for(int i = 0; i < str.length(); i++) { hash = (hash << 4) + str.charAt(i); if(( x = hash & 0xF0000000L) != 0) hash ^= ( x >> 24); hash &= ~x; } return hash; } /*BKDRHash*/ public long BKDRHash(String str) { long seed = 131;//31131131313131131313etc.. long hash = 0; for(int i = 0; i < str.length(); i++) hash = (hash * seed) + str.charAt(i); return hash; } /*SDBMHash*/ public long SDBMHash(String str) { long hash = 0; for(int i = 0; i < str.length(); i++) hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash; return hash; } /*DJBHash*/ public long DJBHash(String str) { long hash = 5381; for(int i = 0; i < str.length(); i++) hash = ((hash << 5) + hash) + str.charAt(i); return hash; } /*DEKHash*/ public long DEKHash(String str) { long hash = str.length(); for(int i = 0; i < str.length(); i++) hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i); return hash; } /*BPHash*/ public long BPHash(String str) { long hash=0; for(int i = 0;i < str.length(); i++) hash = hash << 7 ^ str.charAt(i); return hash; } /*FNVHash*/ public long FNVHash(String str) { long fnv_prime = 0x811C9DC5; long hash = 0; for(int i = 0; i < str.length(); i++) { hash *= fnv_prime; hash ^= str.charAt(i); } return hash; } /*APHash*/ long APHash(String str) { long hash = 0xAAAAAAAA; for(int i = 0; i < str.length(); i++) { if((i & 1) == 0) hash ^=((hash << 7) ^ str.charAt(i) ^ (hash >> 3)); else hash ^= (~((hash << 11) ^ str.charAt(i) ^ (hash >> 5))); } return hash; } }
3:典型哈希算法:
典型的哈希算法包括 MD2、MD4、MD5 和 SHA-1
举例:MD5:
对于任意长度的明文,MD5首先对其进行分组,使得每一组的长度为512位,然后对这些明文分组反复重复处理。
对于每个明文分组的摘要生成过程如下:
(1)将512位的明文分组划分为16个子明文分组,每个子明文分组为32位。
(2)申请4个32位的链接变量,记为A、B、C、D。
(3)子明文分组与链接变量进行第1轮运算。
(4)子明文分组与链接变量进行第2轮运算。
(5)子明文分组与链接变量进行第3轮运算。
(6)子明文分组与链接变量进行第4轮运算。
(7)链接变量与初始链接变量进行求和运算。
(8)链接变量作为下一个明文分组的输入重复进行以上操作。
(9)最后,4个链接变量里面的数据就是MD5摘要。
class
GeneralHashFunctionLibrary
{
/*RSHash*/
public
long
RSHash(String str)
{
int
b = 378551;
int
a = 63689;
long
hash = 0;
for
(
int
i = 0; i < str.length(); i++)
{
hash = hash * a + str.charAt(i);
a = a * b;
}
return
hash;
}
/*JSHash*/
public
long
JSHash(String str)
{
long
hash = 1315423911;
for
(
int
i = 0; i < str.length(); i++)
hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));
return
hash;
}
/*PJWHash*/
public
long
PJWHash(String str)
{
long
BitsInUnsignedInt = (
long
)(4 * 8);
long
ThreeQuarters = (
long
)((BitsInUnsignedInt * 3) / 4);
long
OneEighth = (
long
)(BitsInUnsignedInt / 8);
long
HighBits = (
long
)(0xFFFFFFFF)<<(BitsInUnsignedInt-OneEighth);
long
hash = 0;
long
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;
}
/*ELFHash*/
public
long
ELFHash(String str)
{
long
hash = 0;
long
x = 0;
for
(
int
i = 0; i < str.length(); i++)
{
hash = (hash << 4) + str.charAt(i);
if
(( x = hash & 0xF0000000L) != 0)
hash ^= ( x >> 24);
hash &= ~x;
}
return
hash;
}
/*BKDRHash*/
public
long
BKDRHash(String str)
{
long
seed = 131;
//31131131313131131313etc..
long
hash = 0;
for
(
int
i = 0; i < str.length(); i++)
hash = (hash * seed) + str.charAt(i);
return
hash;
}
/*SDBMHash*/
public
long
SDBMHash(String str)
{
long
hash = 0;
for
(
int
i = 0; i < str.length(); i++)
hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;
return
hash;
}
/*DJBHash*/
public
long
DJBHash(String str)
{
long
hash = 5381;
for
(
int
i = 0; i < str.length(); i++)
hash = ((hash << 5) + hash) + str.charAt(i);
return
hash;
}
/*DEKHash*/
public
long
DEKHash(String str)
{
long
hash = str.length();
for
(
int
i = 0; i < str.length(); i++)
hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);
return
hash;
}
/*BPHash*/
public
long
BPHash(String str)
{
long
hash=0;
for
(
int
i = 0;i < str.length(); i++)
hash = hash << 7 ^ str.charAt(i);
return
hash;
}
/*FNVHash*/
public
long
FNVHash(String str)
{
long
fnv_prime = 0x811C9DC5;
long
hash = 0;
for
(
int
i = 0; i < str.length(); i++)
{
hash *= fnv_prime;
hash ^= str.charAt(i);
}
return
hash;
}
/*APHash*/
long
APHash(String str)
{
long
hash = 0xAAAAAAAA;
for
(
int
i = 0; i < str.length(); i++)
{
if
((i & 1) == 0)
hash ^=((hash << 7) ^ str.charAt(i) ^ (hash >> 3));
else
hash ^= (~((hash << 11) ^ str.charAt(i) ^ (hash >> 5)));
}
return
hash;
}
}