Skip to content

Instantly share code, notes, and snippets.

@pstengel
Created October 2, 2015 15:54
Show Gist options
  • Save pstengel/a8696fba0f0cc6522675 to your computer and use it in GitHub Desktop.
Save pstengel/a8696fba0f0cc6522675 to your computer and use it in GitHub Desktop.
#include <string.h>
#include "fail24.h"
const char VALID_CHARS[] = { '-', '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z' };
const uint64_t OFFSET = 14695981039346656037U;
const uint64_t PRIME = 1099511628211U;
const int VALID_FIRST_IDX = 11;
const int VALID_FIRST_SZ = 26;
const int VALID_LAST_IDX = 1;
const int VALID_LAST_SZ = 36;
uint64_t compute_fnv(const char *string, const size_t len, uint64_t offset) {
uint64_t hash = offset;
char *index = (char *)string;
int i;
for (i = 0; i < len; i++) {
hash = (hash * PRIME) ^ *index;
index++;
}
return hash;
}
void compute_fail24(const char *string, const size_t len, f24_hash_t *hash) {
hash->front = compute_fnv(string, len, OFFSET);
hash->middle = compute_fnv(string, len, hash->front);
hash->front ^= hash->middle;
hash->back = compute_fnv(string, len, hash->middle);
hash->middle ^= hash->back;
hash->back ^= hash->front;
}
char *fail2str(f24_hash_t *hash, char* output) {
char buf[sizeof(f24_hash_t) + 1] = { 0 };
int i;
for (i = 0; i < sizeof(f24_hash_t); i++) {
unsigned char cur = *((unsigned char *)hash + i);
switch (i) {
case 0:
buf[i] = VALID_CHARS[(cur % VALID_FIRST_SZ) + VALID_FIRST_IDX];
break;
case sizeof(f24_hash_t) - 1:
buf[i] = VALID_CHARS[(cur % VALID_LAST_SZ) + VALID_LAST_IDX];
break;
default:
buf[i] = VALID_CHARS[cur % sizeof(VALID_CHARS)];
}
}
return memcpy(output, buf, sizeof(f24_hash_t));
}
#include <stdint.h>
#include <string.h>
typedef struct {
uint64_t front;
uint64_t middle;
uint64_t back;
} f24_hash_t;
extern const uint64_t OFFSET;
extern const uint64_t PRIME;
void compute_fail24(const char *string, size_t len, f24_hash_t *hash);
char *fail2str(f24_hash_t *hash, char* output);
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "fail24.h"
static int get_fail24_str(lua_State *L) {
f24_hash_t hash;
char str_hash[sizeof(f24_hash_t) + 1] = { 0 };
size_t len;
const char *str = luaL_checklstring(L, 1, &len);
compute_fail24(str, len, &hash);
fail2str(&hash, &str_hash[0]);
lua_pushlstring(L, &str_hash[0], sizeof(str_hash) - 1);
return 1;
}
static const luaL_Reg fail24lib[] = {
{ "compute", get_fail24_str },
{ NULL, NULL }
};
LUALIB_API int luaopen_fail24(lua_State *L) {
luaL_register(L, "Fail24", fail24lib);
return 1;
}
# Example
server {
listen 80;
server_name ~^(www\.)?(?<domain>.+)$;
set_by_lua $dns_name 'local fail24 = require("fail24"); return fail24.compute(ngx.var.domain);';
location / {
proxy_pass http://$dns_name.cluster.skynet.local;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment