Source: Internet
Author: User

Label:

In the computational theory, there is no hash function, only one-way function is said. The so-called one-way function, is a complex definition, you can see the computational theory or cryptography data. The "Human" language describes the one-way function: It is easy to calculate the result when a function is given an input, and it is difficult to calculate the input when given the result, which is a single function. Various cryptographic functions can be considered as approximation of one-way functions. A hash function (or a hash function) can also be seen as an approximation of a one-way function. That is, it is close to satisfying the definition of one-way function.

The hash function also has a different meaning. The actual hash function refers to the mapping of a large range to a small range. The goal of mapping a wide range to a small area is often to save space and make data easy to save. In addition, hash functions are often applied to lookups. Therefore, before considering using the hash function, you need to understand several of its limitations:

1. The main principle of hash is to map a large range to a small range, so the number of actual values you enter must be equal to or smaller than the small range. Otherwise there will be a lot of conflict.

2. Because the hash approximates one-way function, you can use it to encrypt the data.

3. Different applications have different requirements for the hash function; For example, the hash function for encryption mainly considers the gap between it and the single function, while the hash function used for searching mainly considers its mapping to a small range of conflict rates.

The hash function applied to encryption has been discussed too much, in the author's blog has a more detailed introduction. Therefore, this article only discusses the hash function used for lookups.

The main object that the hash function applies to is an array (for example, a string), and its target is generally an int type. Here's what we're going to show you in this way.

Generally speaking, the hash function can be easily divided into the following categories:

1. Addition Hash;

2. bit operation Hash;

3. Multiplication hash;

4. Division Hash;

5. Check the table hash;

6. Mixed hash;

The following detailed introduction of the above various methods in the practical application.

An addition hash

The so-called additive hash is the addition of the input elements of a single sum to form the final result. The standard addition hash is constructed as follows:

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);

}

The prime in this case is any prime number, and it can be seen that the value of the result is [0,prime-1].

Two-bit arithmetic hash

This type of hash function fully mixes the input elements by taking advantage of the various bitwise operations (common is shift and XOR). For example, the standard spin hash is constructed as follows:

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);

}

The main feature of this type of hash function is to shift first and then perform various bit operations. For example, the above-calculated hash of the code can also have the following kinds of variants:

1. Hash = (hash<<5) ^ (hash>>27) ^key.charat (i);

2. Hash + = Key.charat (i);

Hash + = (hash << 10);

Hash ^= (hash >> 6);

3. if ((i&1) = = 0)

{

Hash ^= (hash<<7) ^ Key.charat (i) ^ (hash>>3);

}

Else

{

Hash ^= ~ ((hash<<11) ^ Key.charat (i) ^ (hash >>5));

}

4. Hash + = (hash<<5) + Key.charat (i);

5. hash = Key.charat (i) + (hash<<6) + (hash>>16) –hash;

6. Hash ^= ((hash<<5) + Key.charat (i) + (hash>>2));

Three-multiplication Hash

This type of hash function takes advantage of the non-correlation of multiplication (this property of multiplication, the most famous is the random number generation algorithm of the square Kinsoku, although this algorithm is not good). Like what

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;

}

The Hashcode () method of the string class inside the jdk5.0 also uses the multiplication hash. However, it uses a multiplier of 31. The recommended multipliers are: 131, 1313, 13131, 131313, and so on.

The well-known hash functions in this way are:

32-bit FNV algorithm

int m_shift = 0;

public 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;

}

And the improved FNV algorithm:

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;

}

In addition to multiplying by a fixed number, the common ones are multiplied by a constantly changing number, such as:

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);

}

Although the application of the ADLER32 algorithm is not CRC32 widely, it is probably the most famous one in the multiplication hash. For its introduction, you can look at the RFC 1950 specification.

Four-Division Hash

Division, like multiplication, also has a seemingly non-correlation on the surface. However, because the division is too slow, this approach can hardly find a real application. It is important to note that the result of the hash we see in the previous divided by a prime is only intended to guarantee the scope of the result. If you don't need it to limit a range, you can replace "Hash%prime" with the following code: hash = hash ^ (hash>>10) ^ (hash>>20).

Five look-up table hash

The most famous example of tabular hash is the CRC series algorithm. Although the CRC series algorithm itself is not a check table, but the table is one of its fastest way to implement. Here is the implementation of CRC32:

static int crctab[256] = {

Omitted

};

int Crc32 (String key, int hash)

{

int i;

For (Hash=key.length (), i=0; I<key.length (); ++i)

hash = (hash >> 8) ^ crctab[(hash & 0xff) ^ K.charat (i)];

return hash;

}

Notable examples of tabular hashes are: Universal Hashing and Zobrist Hashing. Their tables are randomly generated.

Six mixed hash

The hybrid hash algorithm takes advantage of these various methods. Various common hash algorithms, such as MD5 and Tiger, fall into this range. They are rarely used in search-oriented hash functions.

Evaluation of seven-pair hash algorithm

Http://www.burtleburtle.net/bob/hash/doobs.html This page provides an evaluation of several popular hash algorithms. Our suggestions for the hash function are as follows:

1. Hash of the string. The simplest can use the basic multiplication hash, when the multiplier is 33 o'clock, for English words have a good hash effect (less than 6 lowercase form can guarantee no conflict). A bit more complex can use the FNV algorithm (and its improved form), which is good for long strings, both in speed and in effect.

2. Hash of the long array. You can use the HTTP://BURTLEBURTLE.NET/BOB/C/LOOKUP3.C algorithm, which calculates multiple bytes at once, which is a good speed.

Package Com.hash;public class Hashutils {private static final int crctab[] = {0x00000000, 0x77073096, 0xee0e612c, 0 X990951BA, 0x076dc419, 0x706af48f, 0xe963a535, 0X9E6495A3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0 x97d2d988, 0X09B64C2B, 0X7EB17CBD, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x 1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x6 3066CD9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd2 0D85FD, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdc D60DCF, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8b da50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0X76DC 4190, 0x01db7106, 0X98D220BC, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0X7807C9A2, 0x0f00f934, 0x9609 a88e, 0xe10e9818, 0X7F6A0DBB, 0x086d3d2d, 0x91646c97, 0XE6635C01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf2620 04e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1d DF, 0x15da2d49, 0X8CD37CF3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d 7, 0xa4d1c46d, 0XD3D6F4FB, 0x4369e96a, 0X346ED9FC, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de 5, 0xaa0a4c5f, 0XDD0D7CC9, 0x5005713c, 0X270241AA, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0X206F85B3, 0xb966d409 , 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0XE3630B12, 0x94643b84, 0X0D6D6A3E, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0X806567CB, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0X89D32BE0, 0x10da7a5a, 0X67DD4ACC, 0 XF9B9DF6F, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0XD1BB67F1, 0xa6bc5767, 0X3FB506DD, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0XDF60EFC3, 0x A867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x2 20216B9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5b DEAE1D, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0X0BDBDF21, 0x86d 3d2d4, 0xf1d4e242, 0x68dDb3f8, 0x1fda836e, 0X81BE16CD, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0X66063BCA, 0x1101 0B5C, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0XD70DD2EE, 0x4e048354, 0X3903B3C2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0XD9D65ADC, 0x40df0b66, 0x37d83bf0, 0XA9BCA E53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd706 0x54de5729, 0X23D967BF, 0xb3667a2e, 0xc4614ab8, 0X5D681B02, 0x2a6f2b94, 0xb40bbe37, 0XC30C8EA1, 0X5A05DF1 b, 0x2d02ef8d}; public static int Crc32hash (String key) {int n = key.length (); int hash = n; for (int i = 0; i < n; ++i) hash = (hash >> 8) ^ crctab[(hash & 0xff) ^ Key.charat (i)]; return hash; public static int Additivehash (String key) {int n = key.length (); int hash = n; For (int i = 0; i < n; i++) hash + = Key.charat (i); Return hash ^ (hash >> Ten) ^ (hash >> 20); public static int Rotatinghash (String key) {int n = key.length (); int hash = n; for (int i = 0; i < n; i++) hash = (hash << 4) ^ (hash >>) ^ Key.charat (i); Return (hash & 0x7FFFFFFF); }/** * @param key * @param prime * 131 1313 13131 131313 etc. * @return */public static int Bkdrhash (String key, int prime) {int hash = 0; int n = key.length (); for (int i = 0; i < n; ++i) hash = prime * hash + key.charat (i); Return (hash & 0x7FFFFFFF); } public static int Fnvhash (String key) {final int p = 16777619; int hash = (int) 2166136261L; int n = key.length (); for (int i = 0; i < n; i++) hash = (hash ^ Key.chaRAt (i)) * p; Hash + = Hash << 13; Hash ^= Hash >> 7; Hash + = Hash << 3; Hash ^= Hash >> 17; Hash + = Hash << 5; Return (hash & 0x7FFFFFFF); } public static int Rshash (String key) {int b = 378551; int a = 63689; int hash = 0; int n = key.length (); for (int i = 0; i < n; i++) {hash = hash * A + key.charat (i); A = a * b; } return (hash & 0x7FFFFFFF); } public static int Jshash (String key) {int hash = 1315423911; int n = key.length (); for (int i = 0; i < n; i++) {hash ^= (hash << 5) + Key.charat (i) + (hash >> 2)); } return (hash & 0x7FFFFFFF); }//P. J. Weinberger Hash Function public static int Pjwhash (String key) {int bitsinunignedint = 32 ; int threequarters = 24; int oneeighth = 4; int highbits = (0xFFFFFFFF) << (bitsinunignedint-oneeighth); int hash = 0; int test = 0; int n = key.length (); for (int i = 0; i < n; i++) {hash = (hash << oneeighth) + Key.charat (i); if (test = hash & highbits)! = 0) {hash = (hash ^ (test >> threequarters)) & (~highbits) ); }} return (hash & 0x7FFFFFFF); } public static int Elfhash (String key) {int h = 0; int n = key.length (); for (int i = 0; i < n; i++) {h = (H << 4) + Key.charat (i); Long g = h & 0xf0000000l; if (g! = 0) {h ^= g >> 24; H &= ~g; }} return (H & 0x7FFFFFFF); }//SDBM hash Function public static int Sdbmhash (String key) {int hash = 0;int n = key.length (); for (int i = 0; i < n; i++) {hash = Key.charat (i) + (hash << 6) + (hash << +)-hash; } return (hash & 0x7FFFFFFF); }//DJB hash Function public static int Djbhash (String key) {int hash = 5381; int n = key.length (); for (int i = 0; i < n; i++) {hash + = (hash << 5) + Key.charat (i); } return (hash & 0x7FFFFFFF); }//AP hash Function public static int Aphash (String key) {int hash = 0; int n = key.length (); for (int i = 0; i < n; i++) {if ((I & 1) = = 0) {Hash ^= (hash << 7) ^ key.ch Arat (i) ^ (hash >> 3)); } else {hash ^= ((hash << one) ^ Key.charat (i) ^ (hash >> 5)); }} return (hash & 0x7FFFFFFF); } }

Apply hash function