hkey_t hash_fnv1a(const hvalue_t key, uint32_t hash) { const unsigned char* ptr = (const unsigned char*) &key; hash = fnv1a(*ptr++, hash); hash = fnv1a(*ptr++, hash); hash = fnv1a(*ptr++, hash); return fnv1a(*ptr , hash); }
uint32_t gen_hash(char *buf, int len) { uint32_t hash = len * 97; if (len <= 1024){ hash += fnv1a(buf, len); }else{ hash += fnv1a(buf, 512); hash *= 97; hash += fnv1a(buf + len - 512, 512); } return hash; }
bool hash_del(atom_p obj, const char* key) { assert(obj->type == T_OBJ || obj->type == T_ENV); uint32_t hash = fnv1a(key); size_t index = hash % obj->obj.cap; while ( !(obj->obj.slots[index].key == OBJ_SLOT_FREE) ) { if ( obj->obj.slots[index].hash == hash && strcmp(obj->obj.slots[index].key, key) == 0 ) { obj->obj.slots[index].hash = 0; obj->obj.slots[index].key = OBJ_SLOT_DELETED; obj->obj.slots[index].value = NULL; obj->obj.len--; obj->obj.deleted++; if (obj->obj.len < obj->obj.cap * 0.2) hash_resize(obj, obj->obj.cap / 2); return true; } index = (index + 1) % obj->obj.cap; } return false; }
// //hash for a key is computed based on the hash type set // uint64_t NVM_KV_Hash_Func::key_hash(uint8_t *key, uint32_t key_len, uint32_t pool_id, uint32_t hash_len, bool align) { uint64_t hash = 0; if (key == NULL || key_len == 0 || hash_len == 0) { return 0; } switch(m_hashFunType) { case FNV1A: hash = fnv1a(key, key_len, pool_id); break; default: return 0; } //generally hashing algorithms produce 32,64,128..power of 2 hashes //for hash value that are not power of two, xor fold to appropriate //bits if (hash_len) { if (hash_len > M_TINY_HASH_LEN) { hash = (hash >> hash_len) ^ (hash & (((uint64_t) 1 << hash_len) - 1)); } else {
Variable get_float_hash(Number number) { std::stringstream ss; ss << number; // Cheating is easy. I like easy. Variable var = fnv1a(number); string_hash_map[ss.str()] = var; reverse_variable_name_lookup[var] = ss.str(); return var; }
atom_p hash_get(atom_p obj, const char* key) { assert(obj->type == T_OBJ || obj->type == T_ENV); uint32_t hash = fnv1a(key); size_t index = hash % obj->obj.cap; while( !(obj->obj.slots[index].key == OBJ_SLOT_FREE) ) { if ( obj->obj.slots[index].hash == hash && strcmp(obj->obj.slots[index].key, key) == 0 ) return obj->obj.slots[index].value; index = (index + 1) % obj->obj.cap; } return NULL; }
void PEFormat::processExport() { IMAGE_DATA_DIRECTORY *exportDirectory = getDataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT); IMAGE_EXPORT_DIRECTORY *directory = reinterpret_cast<IMAGE_EXPORT_DIRECTORY *>(getDataPointerOfRVA(exportDirectory->VirtualAddress)); size_t exportTableBase = exportDirectory->VirtualAddress; size_t exportTableSize = exportDirectory->Size; if(!directory) return; bool *checker = new bool[directory->NumberOfFunctions]; for(size_t i = 0; i < directory->NumberOfFunctions; i ++) checker[i] = false; uint32_t *addressOfFunctions = reinterpret_cast<uint32_t *>(getDataPointerOfRVA(directory->AddressOfFunctions)); uint32_t *addressOfNames = reinterpret_cast<uint32_t *>(getDataPointerOfRVA(directory->AddressOfNames)); uint16_t *ordinals = reinterpret_cast<uint16_t *>(getDataPointerOfRVA(directory->AddressOfNameOrdinals)); for(size_t i = 0; i < directory->NumberOfNames; i ++) { ExportFunction entry; if(addressOfNames && addressOfNames[i]) { entry.name.assign(reinterpret_cast<const char *>(getDataPointerOfRVA(addressOfNames[i]))); entry.nameHash = fnv1a(entry.name.c_str(), entry.name.length()); } entry.ordinal = ordinals[i]; entry.address = addressOfFunctions[entry.ordinal]; checker[entry.ordinal] = true; entry.ordinal += directory->Base; entry.forward = checkExportForwarder(entry.address, exportTableBase, exportTableSize); exports_.push_back(std::move(entry)); } for(size_t i = 0; i < directory->NumberOfFunctions; i ++) { if(checker[i] == true) continue; //entry without names ExportFunction entry; entry.ordinal = i + directory->Base; entry.address = addressOfFunctions[i]; entry.forward = checkExportForwarder(entry.address, exportTableBase, exportTableSize); exports_.push_back(std::move(entry)); } delete [] checker; }
Variable get_string_hash(std::string string) { if(string_hash_map.find(string) == string_hash_map.end()) { Variable var = fnv1a(string.c_str()); string_hash_map[string] = var; reverse_variable_name_lookup[var] = string; return var; } else { return string_hash_map[string]; } }
void dc_rebuild(Codec *dc) { int i; free(dc->rdict); dc->rdict_size = rdict_size(dc->dict_size); dc->rdict = (short*) malloc(sizeof(short) * dc->rdict_size); memset(dc->rdict, 0, sizeof(short) * dc->rdict_size); for (i=1; i<dc->dict_used; i++) { uint32_t h = fnv1a(dc->dict[i]->fmt, strlen(dc->dict[i]->fmt)) % dc->rdict_size; while (dc->rdict[h] > 0) { h ++; if (h == dc->rdict_size) h = 0; } dc->rdict[h] = i; } }
void hash_set(atom_p obj, const char* key, atom_p value) { assert(obj->type == T_OBJ || obj->type == T_ENV); if (obj->obj.len + obj->obj.deleted + 1 > obj->obj.cap * 0.7) hash_resize(obj, (obj->obj.cap == 0) ? 2 : obj->obj.cap * 2); uint32_t hash = fnv1a(key); size_t index = hash % obj->obj.cap; while ( !(obj->obj.slots[index].key == OBJ_SLOT_FREE || obj->obj.slots[index].key == OBJ_SLOT_DELETED) ) { if ( obj->obj.slots[index].hash == hash && strcmp(obj->obj.slots[index].key, key) == 0 ) break; index = (index + 1) % obj->obj.cap; } if (obj->obj.slots[index].key == OBJ_SLOT_DELETED) obj->obj.deleted--; obj->obj.len++; obj->obj.slots[index].hash = hash; obj->obj.slots[index].key = key; obj->obj.slots[index].value = value; }
hash_t hash(const char* start, size_t len){ return fnv1a(start, len); }
void PEFormat::processImport() { IMAGE_DATA_DIRECTORY *importDirectory = getDataDirectory(IMAGE_DIRECTORY_ENTRY_IMPORT); IMAGE_IMPORT_DESCRIPTOR *descriptor = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR *>(getDataPointerOfRVA(importDirectory->VirtualAddress)); if(!descriptor) return; while(true) { if(descriptor->OriginalFirstThunk == 0) break; Import import; uint8_t *libraryNamePtr = getDataPointerOfRVA(descriptor->Name); import.libraryName.assign(reinterpret_cast<const char *>(libraryNamePtr)); uint32_t *nameEntryPtr = reinterpret_cast<uint32_t *>(getDataPointerOfRVA(descriptor->OriginalFirstThunk)); uint64_t iat = descriptor->FirstThunk; while(true) { if(*nameEntryPtr == 0) break; ImportFunction function; function.ordinal = -1; function.iat = iat; if((info_.architecture == ArchitectureWin32AMD64 && (*reinterpret_cast<uint64_t *>(nameEntryPtr) & IMAGE_ORDINAL_FLAG64)) || (*reinterpret_cast<uint32_t *>(nameEntryPtr) & IMAGE_ORDINAL_FLAG32)) { if(info_.architecture == ArchitectureWin32AMD64) function.ordinal = *reinterpret_cast<uint64_t *>(nameEntryPtr) & 0xffff; else function.ordinal = *reinterpret_cast<uint32_t *>(nameEntryPtr) & 0xffff; } else { IMAGE_IMPORT_BY_NAME *nameEntry; if(info_.architecture == ArchitectureWin32AMD64) nameEntry = reinterpret_cast<IMAGE_IMPORT_BY_NAME *>(getDataPointerOfRVA(static_cast<uint32_t>(*reinterpret_cast<uint64_t *>(nameEntryPtr)))); else nameEntry = reinterpret_cast<IMAGE_IMPORT_BY_NAME *>(getDataPointerOfRVA(*reinterpret_cast<uint32_t *>(nameEntryPtr))); function.name.assign(reinterpret_cast<const char *>(nameEntry->Name)); function.nameHash = fnv1a(function.name.c_str(), function.name.length()); } if(info_.architecture == ArchitectureWin32AMD64) { nameEntryPtr += 2; iat += 8; } else { nameEntryPtr ++; iat += 4; } import.functions.push_back(std::move(function)); } imports_.push_back(std::move(import)); descriptor ++; } }
inline pthread_mutex_t* get_mutex(HStore *store, char *key) { uint32_t i = fnv1a(key, strlen(key)) % NUM_OF_MUTEX; return &store->locks[i]; }
inline int get_index(HStore *store, char *key) { if (store->height == 0) return 0; uint32_t h = fnv1a(key, strlen(key)); return h >> ((8 - store->height) * 4); }
int dc_encode(Codec* dc, char* buf, const char* src, int len) { if (src == NULL || buf == NULL){ return 0; } if (dc != NULL && len > 6 && len < 100 && src[0] > 0){ int m=0; char fmt[255]; bool hex[20]; char num[20][10]; int32_t args[10]; const char *p=src, *q=src + len; char *dst=fmt; while(p<q){ if (*p == '%' || *p == '@' || *p == ':'){ // not supported format goto RET; } if (*p >= '1' && *p <= '9' || *p >= 'a' && *p <= 'f'){ char *nd = num[m]; hex[m] = false; while(p < q && (*p >= '0' && *p <= '9' || *p >= 'a' && *p <= 'f')) { if (*p >= 'a' && *p <= 'f') hex[m] = true; *nd ++ = *p ++; if (hex[m] && nd-num[m] >= 8 || !hex[m] && nd-num[m] >=9) { break; } } // 8digit+1hex, pop it if (hex[m] && nd-num[m]==9) { nd--; p--; hex[m] = false; } *nd = 0; if (hex[m] && nd - num[m] >= 4){ *dst ++ = '%'; *dst ++ = 'x'; args[m] = strtol(num[m], NULL, 16); m ++; } else if (!hex[m] && nd - num[m] >= 3) { *dst ++ = '%'; *dst ++ = 'd'; args[m] = atoi(num[m]); m ++; }else{ memcpy(dst, num[m], nd - num[m]); dst += nd - num[m]; } }else{ *dst ++ = *p++; } } *dst = 0; // ending 0 int flen = dst - fmt, prefix; if (m > 0 && m <= 2){ Fmt **dict = dc->dict; uint32_t h = fnv1a(fmt, flen) % dc->rdict_size; // test hash collision while (dc->rdict[h] > 0 && strcmp(fmt, dict[dc->rdict[h]]->fmt) != 0) { h ++; if (h == dc->rdict_size) h = 0; } int rh = dc->rdict[h]; if (rh == 0){ if (dc->dict_used < dc->dict_size) { dict[dc->dict_used] = (Fmt*) malloc(sizeof(Fmt) + flen - 7 + 1); dict[dc->dict_used]->nargs = m; memcpy(dict[dc->dict_used]->fmt, fmt, flen + 1); // fprintf(stderr, "new fmt %d: %s <= %s\n", dc->dict_used, fmt, src); dc->rdict[h] = rh = dc->dict_used ++; if (dc->dict_used == dc->dict_size && dc->dict_size < MAX_DICT_SIZE) { dc_enlarge(dc); } } else { fprintf(stderr, "not captched fmt: %s <= %s\n", fmt, src); dc->rdict[h] = rh = -1; // not again } } if (rh > 0) { if (rh < 64) { prefix = 1; *buf = - rh; }else{ prefix = 2; *buf = - (rh & 0x3f) - 64; *(unsigned char*)(buf+1) = rh >> 6; } memcpy(buf+prefix, args, sizeof(int32_t)*m); return prefix + m * sizeof(int32_t); } }