blob: a20b90cc04c690bad57520b0f2d5baef61b5649a [file] [log] [blame]
Bhaskar98634f02013-10-29 23:30:51 -04001/*
2 * Hash function implementation
3 *
4 * See mailing list thread on "Consistent hashing alternative to sdbm"
5 * http://marc.info/?l=haproxy&m=138213693909219
6 *
7 * Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 *
14 */
15
16
Willy Tarreau8d366972020-05-27 16:10:29 +020017#include <haproxy/hash.h>
Bhaskar98634f02013-10-29 23:30:51 -040018
19
Willy Tarreau340b07e2020-01-15 10:54:42 +010020unsigned int hash_wt6(const void *input, int len)
Willy Tarreaua0f42712013-11-14 14:30:35 +010021{
Willy Tarreau340b07e2020-01-15 10:54:42 +010022 const unsigned char *key = input;
Willy Tarreaua0f42712013-11-14 14:30:35 +010023 unsigned h0 = 0xa53c965aUL;
24 unsigned h1 = 0x5ca6953aUL;
25 unsigned step0 = 6;
26 unsigned step1 = 18;
27
28 for (; len > 0; len--) {
29 unsigned int t;
30
Willy Tarreau340b07e2020-01-15 10:54:42 +010031 t = *key;
Willy Tarreaua0f42712013-11-14 14:30:35 +010032 key++;
33
34 h0 = ~(h0 ^ t);
35 h1 = ~(h1 + t);
36
37 t = (h1 << step0) | (h1 >> (32-step0));
38 h1 = (h0 << step1) | (h0 >> (32-step1));
39 h0 = t;
40
41 t = ((h0 >> 16) ^ h1) & 0xffff;
42 step0 = t & 0x1F;
43 step1 = t >> 11;
44 }
45 return h0 ^ h1;
46}
47
Willy Tarreau340b07e2020-01-15 10:54:42 +010048unsigned int hash_djb2(const void *input, int len)
Bhaskar98634f02013-10-29 23:30:51 -040049{
Willy Tarreau340b07e2020-01-15 10:54:42 +010050 const unsigned char *key = input;
Dan Dubovikbd57a9f2014-07-08 08:51:03 -070051 unsigned int hash = 5381;
Bhaskar98634f02013-10-29 23:30:51 -040052
53 /* the hash unrolled eight times */
54 for (; len >= 8; len -= 8) {
55 hash = ((hash << 5) + hash) + *key++;
56 hash = ((hash << 5) + hash) + *key++;
57 hash = ((hash << 5) + hash) + *key++;
58 hash = ((hash << 5) + hash) + *key++;
59 hash = ((hash << 5) + hash) + *key++;
60 hash = ((hash << 5) + hash) + *key++;
61 hash = ((hash << 5) + hash) + *key++;
62 hash = ((hash << 5) + hash) + *key++;
63 }
64 switch (len) {
65 case 7: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
66 case 6: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
67 case 5: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
68 case 4: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
69 case 3: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
70 case 2: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
71 case 1: hash = ((hash << 5) + hash) + *key++; break;
72 default: /* case 0: */ break;
73 }
74 return hash;
75}
76
Willy Tarreau340b07e2020-01-15 10:54:42 +010077unsigned int hash_sdbm(const void *input, int len)
Bhaskar98634f02013-10-29 23:30:51 -040078{
Willy Tarreau340b07e2020-01-15 10:54:42 +010079 const unsigned char *key = input;
Dan Dubovikbd57a9f2014-07-08 08:51:03 -070080 unsigned int hash = 0;
Bhaskar98634f02013-10-29 23:30:51 -040081 int c;
82
83 while (len--) {
84 c = *key++;
85 hash = c + (hash << 6) + (hash << 16) - hash;
86 }
87
88 return hash;
89}
90
Willy Tarreauc829ee42015-01-20 19:17:09 +010091/* Small yet efficient CRC32 calculation loosely inspired from crc32b found
92 * here : http://www.hackersdelight.org/hdcodetxt/crc.c.txt
93 * The magic value represents the polynom with one bit per exponent. Much
94 * faster table-based versions exist but are pointless for our usage here,
95 * this hash already sustains gigabit speed which is far faster than what
96 * we'd ever need. Better preserve the CPU's cache instead.
97 */
Willy Tarreau340b07e2020-01-15 10:54:42 +010098unsigned int hash_crc32(const void *input, int len)
Willy Tarreauc829ee42015-01-20 19:17:09 +010099{
Willy Tarreau340b07e2020-01-15 10:54:42 +0100100 const unsigned char *key = input;
Willy Tarreauc829ee42015-01-20 19:17:09 +0100101 unsigned int hash;
102 int bit;
Bhaskar98634f02013-10-29 23:30:51 -0400103
Willy Tarreauc829ee42015-01-20 19:17:09 +0100104 hash = ~0;
105 while (len--) {
106 hash ^= *key++;
107 for (bit = 0; bit < 8; bit++)
108 hash = (hash >> 1) ^ ((hash & 1) ? 0xedb88320 : 0);
109 }
110 return ~hash;
111}
Emmanuel Hocdet6afd8982018-02-05 15:23:39 +0100112
113/* CRC32c poly 0x11EDC6F41 (RFC4960, Appendix B [8].) */
114static const uint32_t crctable[256] = {
115 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
116 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
117 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
118 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
119 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
120 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
121 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
122 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
123 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
124 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
125 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
126 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
127 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
128 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
129 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
130 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
131 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
132 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
133 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
134 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
135 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
136 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
137 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
138 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
139 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
140 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
141 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
142 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
143 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
144 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
145 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
146 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
147 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
148 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
149 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
150 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
151 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
152 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
153 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
154 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
155 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
156 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
157 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
158 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
159 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
160 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
161 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
162 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
163 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
164 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
165 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
166 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
167 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
168 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
169 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
170 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
171 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
172 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
173 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
174 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
175 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
176 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
177 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
178 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
179};
180
Willy Tarreau340b07e2020-01-15 10:54:42 +0100181uint32_t hash_crc32c(const void *input, int len)
Emmanuel Hocdet6afd8982018-02-05 15:23:39 +0100182{
Willy Tarreau340b07e2020-01-15 10:54:42 +0100183 const unsigned char *buf = input;
Emmanuel Hocdet6afd8982018-02-05 15:23:39 +0100184 uint32_t crc = 0xffffffff;
185 while (len-- > 0) {
186 crc = (crc >> 8) ^ crctable[(crc ^ (*buf++)) & 0xff];
187 }
188 return (crc ^ 0xffffffff);
189}