From this page: http://www.cse.yorku.ca/~oz/hash.html
import os,sys def tt(ll): return (ll & 0xffffffff) def sdbm(inpt, leng): hshs = 0 for x in range(0, leng): hshs = tt(ord(inpt[x]) + tt(hshs << 6) + tt(hshs << 16) - hshs) return hshs def sdbm_hash(inpt, leng): mixs = [1, 6, 16, 13, 33, 27, 67, 55, 123] hshs = [0, 0, 0, 0, 0, 0, 0, 0, 0] more = 0 rnds = len(hshs) for z in range(0, rnds*3): hshs[0] = tt((hshs[0] + mixs[z%rnds]) * mixs[z%rnds]) for x in range(0, leng): hshs[0] = (hshs[0] & 0xffff) hshs[0] = tt(ord(inpt[x]) + (hshs[0] << 6) + (hshs[0] << 16) - hshs[0]) more = (more ^ (hshs[rnds-1] >> 16)) for y in range(rnds-1, 0, -1): hshs[y] = tt((hshs[y] << 16) | (hshs[y-1] >> 16)) hshs[y-1] = (hshs[y-1] & 0xffff) hshs[0] = (hshs[0] ^ more) o = "" for h in hshs[1:]: for x in range(3, -1, -1): o += chr((h>>(x*8))&0xff) return o def stoh(s): return "".join([hex(ord(c))[2:].rjust(2, '0') for c in s]) m = sys.argv[1] ; l = len(m) print(stoh(sdbm_hash(m, l)), sdbm(m, l), m, l)
$ python hash.py "b" ('197f907989061db579beba252025bfbf7f4848a47da0e5a9bc8eb73c6fdb8904', 98, 'b', 1) $ python hash.py "c" ('f39b31f66506067376f8f88f620e731cd4292a6aeb71da43d297fffc3f5f92c4', 99, 'c', 1) $ python hash.py "bb" ('d427d6ba1edaabab2ba3c6ddd70ccf3d0ceff23fcd6de3d2c0af7d0ac95dd62d', 6428800, 'bb', 2) $ python hash.py "bc" ('4bfdd409d3de82913ba7405894f444d8858a539abe98e312d64474abf6b68e3a', 6428801, 'bc', 2) $ ./hash "this is a test" [dc053c4426ce396ace93a2817b388c465bb5188336d5f8816384a1cef0a2039d] [1655286693] [this is a test] [14] $ ./hash "this is a tesu" [cfbb3301ae39658cf1a1874dd48d8dbf9da4aee0831f781e30066be5f67eb819] [1655286694] [this is a tesu] [14]
#include <stdio.h> #include <string.h> unsigned int sdbm(char *inpt, int leng) { unsigned int hshs = 0; for (int x = 0; x < leng; ++x) { hshs = (inpt[x] + (hshs << 6) + (hshs << 16) - hshs); } return hshs; } void sdbm_hash(unsigned char *outp, unsigned char *inpt, int leng) { unsigned int mixs[] = {1, 6, 16, 13, 33, 27, 67, 55, 123}; unsigned int hshs[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned int more = 0; int rnds = 9; for (int z = 0; z < rnds*3; ++z) { hshs[0] = ((hshs[0] + mixs[z%rnds]) * mixs[z%rnds]); for (int x = 0; x < leng; ++x) { hshs[0] = (hshs[0] & 0xffff); hshs[0] = (inpt[x] + (hshs[0] << 6) + (hshs[0] << 16) - hshs[0]); more = (more ^ (hshs[rnds-1] >> 16)); for (int y = rnds-1; y > 0; --y) { hshs[y] = ((hshs[y] << 16) | (hshs[y-1] >> 16)); hshs[y-1] = (hshs[y-1] & 0xffff); } hshs[0] = (hshs[0] ^ more); } } for (int x = 1, y = 0; x < rnds; ++x) { for (int z = 3; z > -1; --z, ++y) { outp[y] = ((hshs[x] >> (z * 8)) & 0xff); } } } void stoh(char *outp, unsigned char *inpt) { char *hexs = "0123456789abcdef"; for (int x = 0, y = 0; x < 32; ++x) { outp[y] = hexs[(inpt[x] >> 4) & 0xf]; ++y; outp[y] = hexs[inpt[x] & 0xf]; ++y; } } int main(int argc, char *argv[]) { char *m = argv[1]; int l = strlen(m); unsigned char h[32]; char o[65]; bzero(o, 65); sdbm_hash(h, (unsigned char *)m, l); stoh(o, h); printf("[%s] [%u] [%s] [%d]\n", o, sdbm(m, l), m, l); return 0; }