spa/sigil.c

100 lines
2.6 KiB
C

#include <stdio.h>
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <time.h>
*/
#include <ctype.h> //toupper
#include "global.h"
/* SIGILS
A sigil is shortcut to a URL previously seen by the system and databased.
In this application, a sigil corresponds to a 20-bit value, encoded as a 4-char
string (using only capital letters and numbers, but not O,I,0,or 1 to avoid
confusion). Sigils are meant to be somewhat easy to recognize.
Sigils are used as indices into the URL database, resolving as URLS.
Sigils are generated as FNV1a hashes of URLs provided.
*/
#define IDX_SIZE (0x100000 * IDX_ENTRY_SIZE)
#define IDX_MASK 0xFFFFF
#define FNV_OFFSET 14695981039346656037UL
#define FNV_PRIME 1099511628211UL
// working character map, 32 characters
static char charmap[]="ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
/*******************************************************************************
******************************************************************************/
/*******************************************************************************
string_hash - generate a FNV1A hash of 20 bits
******************************************************************************/
U32 string_hash(const char* str) {
uint64_t hash = FNV_OFFSET;
for (const char* p = str; *p; p++) {
hash ^= (uint64_t)(unsigned char)(*p);
hash *= FNV_PRIME;
}
return hash & IDX_MASK;
}
/*******************************************************************************
char_to_c5bit Convert a 5-bit encoded as a character to a 5-bit value
******************************************************************************/
int char_to_c5bit(int ch){
int i;
int c = toupper(ch);
for(i=31;i>=0;i--)
if(c==charmap[i])
break;
return i;
}
/*******************************************************************************
idx_sigil Convert a 20-bit idx to a 4-char sigil
******************************************************************************/
void idx_sigil(U32 idx,char* sigil){
for(int i=15;i>=0;i-=5){
*sigil++ = charmap[0x1F & (idx>>i)];
}
*sigil=0;
}
/*******************************************************************************
sigil_idx Convert a 4-char null-termed sigil to a 20-bit idx
******************************************************************************/
U32 sigil_idx(char* sigil){
int result = 0;
for(int i=0;i<4;i++){
int code = char_to_c5bit(*sigil++);
if(result<0)
return -1;
result = (result << 5) + code;
}
// printf("Converted sigil %s to idx %X\n",sigil,result);
return result;
}