100 lines
2.6 KiB
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;
|
|
}
|