blob: 5c92e944f84c023a5cc3aeec82e289958c67f0eb [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 Tarreaucff89872022-11-14 07:18:42 +010017#include <haproxy/compiler.h>
Willy Tarreau8d366972020-05-27 16:10:29 +020018#include <haproxy/hash.h>
Bhaskar98634f02013-10-29 23:30:51 -040019
20
Willy Tarreau340b07e2020-01-15 10:54:42 +010021unsigned int hash_wt6(const void *input, int len)
Willy Tarreaua0f42712013-11-14 14:30:35 +010022{
Willy Tarreau340b07e2020-01-15 10:54:42 +010023 const unsigned char *key = input;
Willy Tarreaua0f42712013-11-14 14:30:35 +010024 unsigned h0 = 0xa53c965aUL;
25 unsigned h1 = 0x5ca6953aUL;
26 unsigned step0 = 6;
27 unsigned step1 = 18;
28
29 for (; len > 0; len--) {
30 unsigned int t;
31
Willy Tarreau340b07e2020-01-15 10:54:42 +010032 t = *key;
Willy Tarreaua0f42712013-11-14 14:30:35 +010033 key++;
34
35 h0 = ~(h0 ^ t);
36 h1 = ~(h1 + t);
37
38 t = (h1 << step0) | (h1 >> (32-step0));
39 h1 = (h0 << step1) | (h0 >> (32-step1));
40 h0 = t;
41
42 t = ((h0 >> 16) ^ h1) & 0xffff;
43 step0 = t & 0x1F;
44 step1 = t >> 11;
45 }
46 return h0 ^ h1;
47}
48
Willy Tarreau340b07e2020-01-15 10:54:42 +010049unsigned int hash_djb2(const void *input, int len)
Bhaskar98634f02013-10-29 23:30:51 -040050{
Willy Tarreau340b07e2020-01-15 10:54:42 +010051 const unsigned char *key = input;
Dan Dubovikbd57a9f2014-07-08 08:51:03 -070052 unsigned int hash = 5381;
Bhaskar98634f02013-10-29 23:30:51 -040053
54 /* the hash unrolled eight times */
55 for (; len >= 8; len -= 8) {
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 hash = ((hash << 5) + hash) + *key++;
64 }
65 switch (len) {
Willy Tarreaucff89872022-11-14 07:18:42 +010066 case 7: hash = ((hash << 5) + hash) + *key++; __fallthrough;
67 case 6: hash = ((hash << 5) + hash) + *key++; __fallthrough;
68 case 5: hash = ((hash << 5) + hash) + *key++; __fallthrough;
69 case 4: hash = ((hash << 5) + hash) + *key++; __fallthrough;
70 case 3: hash = ((hash << 5) + hash) + *key++; __fallthrough;
71 case 2: hash = ((hash << 5) + hash) + *key++; __fallthrough;
Bhaskar98634f02013-10-29 23:30:51 -040072 case 1: hash = ((hash << 5) + hash) + *key++; break;
73 default: /* case 0: */ break;
74 }
75 return hash;
76}
77
Willy Tarreau340b07e2020-01-15 10:54:42 +010078unsigned int hash_sdbm(const void *input, int len)
Bhaskar98634f02013-10-29 23:30:51 -040079{
Willy Tarreau340b07e2020-01-15 10:54:42 +010080 const unsigned char *key = input;
Dan Dubovikbd57a9f2014-07-08 08:51:03 -070081 unsigned int hash = 0;
Bhaskar98634f02013-10-29 23:30:51 -040082 int c;
83
84 while (len--) {
85 c = *key++;
86 hash = c + (hash << 6) + (hash << 16) - hash;
87 }
88
89 return hash;
90}
91
Willy Tarreauc829ee42015-01-20 19:17:09 +010092/* Small yet efficient CRC32 calculation loosely inspired from crc32b found
93 * here : http://www.hackersdelight.org/hdcodetxt/crc.c.txt
94 * The magic value represents the polynom with one bit per exponent. Much
95 * faster table-based versions exist but are pointless for our usage here,
96 * this hash already sustains gigabit speed which is far faster than what
97 * we'd ever need. Better preserve the CPU's cache instead.
98 */
Willy Tarreau340b07e2020-01-15 10:54:42 +010099unsigned int hash_crc32(const void *input, int len)
Willy Tarreauc829ee42015-01-20 19:17:09 +0100100{
Willy Tarreau340b07e2020-01-15 10:54:42 +0100101 const unsigned char *key = input;
Willy Tarreauc829ee42015-01-20 19:17:09 +0100102 unsigned int hash;
103 int bit;
Bhaskar98634f02013-10-29 23:30:51 -0400104
Willy Tarreauc829ee42015-01-20 19:17:09 +0100105 hash = ~0;
106 while (len--) {
107 hash ^= *key++;
108 for (bit = 0; bit < 8; bit++)
109 hash = (hash >> 1) ^ ((hash & 1) ? 0xedb88320 : 0);
110 }
111 return ~hash;
112}
Emmanuel Hocdet6afd8982018-02-05 15:23:39 +0100113
114/* CRC32c poly 0x11EDC6F41 (RFC4960, Appendix B [8].) */
115static const uint32_t crctable[256] = {
116 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
117 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
118 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
119 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
120 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
121 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
122 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
123 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
124 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
125 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
126 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
127 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
128 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
129 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
130 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
131 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
132 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
133 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
134 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
135 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
136 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
137 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
138 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
139 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
140 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
141 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
142 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
143 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
144 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
145 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
146 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
147 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
148 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
149 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
150 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
151 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
152 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
153 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
154 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
155 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
156 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
157 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
158 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
159 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
160 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
161 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
162 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
163 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
164 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
165 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
166 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
167 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
168 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
169 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
170 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
171 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
172 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
173 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
174 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
175 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
176 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
177 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
178 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
179 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
180};
181
Willy Tarreau340b07e2020-01-15 10:54:42 +0100182uint32_t hash_crc32c(const void *input, int len)
Emmanuel Hocdet6afd8982018-02-05 15:23:39 +0100183{
Willy Tarreau340b07e2020-01-15 10:54:42 +0100184 const unsigned char *buf = input;
Emmanuel Hocdet6afd8982018-02-05 15:23:39 +0100185 uint32_t crc = 0xffffffff;
186 while (len-- > 0) {
187 crc = (crc >> 8) ^ crctable[(crc ^ (*buf++)) & 0xff];
188 }
189 return (crc ^ 0xffffffff);
190}