ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
fnv1a.h
Go to the documentation of this file.
1#pragma once
2
24#include <stddef.h>
25#include <stdint.h>
26
27// NOTE: This is a low-level hash utility. To avoid circular dependencies with
28// asciichat_errno.h and common.h, we don't log errors here. Invalid inputs return 0.
29
30/* ============================================================================
31 * FNV-1a Constants
32 * ============================================================================ */
33
35#define FNV1A_32_OFFSET_BASIS 2166136261ULL
36
38#define FNV1A_32_PRIME 16777619ULL
39
41#define FNV1A_32_MASK 0xFFFFFFFFULL
42
43/* ============================================================================
44 * Macros
45 * ============================================================================ */
46
48#define FNV1A_INIT(hash) uint64_t hash = FNV1A_32_OFFSET_BASIS;
49
51#define FNV1A_32_HASH(hash, byte) \
52 do { \
53 (hash) = (((hash) ^ (uint64_t)(byte)) * FNV1A_32_PRIME) & FNV1A_32_MASK; \
54 } while (0)
55
56/* ============================================================================
57 * FNV-1a Hash Functions
58 * ============================================================================ */
59
71static inline uint32_t fnv1a_hash_bytes(const void *data, size_t len) {
72 // Return 0 for invalid input (no error logging to avoid circular dependencies)
73 if (!data || len == 0) {
74 return 0;
75 }
76
78 const unsigned char *bytes = (const unsigned char *)data;
79 const unsigned char *end = bytes + len;
80
81 while (bytes < end) {
82 uint64_t byte = (uint64_t)*bytes++;
83 hash = ((hash ^ byte) * FNV1A_32_PRIME) & FNV1A_32_MASK;
84 }
85
86 return (uint32_t)hash;
87}
88
99static inline uint32_t fnv1a_hash_string(const char *str) {
100 // Return 0 for invalid input (no error logging to avoid circular dependencies)
101 if (!str) {
102 return 0;
103 }
104
106 const unsigned char *p = (const unsigned char *)str;
107
108 while (*p) {
109 uint64_t byte = (uint64_t)*p++;
110 hash = ((hash ^ byte) * FNV1A_32_PRIME) & FNV1A_32_MASK;
111 }
112
113 return (uint32_t)hash;
114}
115
126static inline uint32_t fnv1a_hash_uint32(uint32_t value) {
128
129 // Hash each byte of the 32-bit value
130 FNV1A_32_HASH(hash, (value >> 0) & FNV1A_32_MASK);
131 FNV1A_32_HASH(hash, (value >> 8) & FNV1A_32_MASK);
132 FNV1A_32_HASH(hash, (value >> 16) & FNV1A_32_MASK);
133 FNV1A_32_HASH(hash, (value >> 24) & FNV1A_32_MASK);
134
135 return (uint32_t)hash;
136}
137
148static inline uint32_t fnv1a_hash_uint64(uint64_t value) {
150
151 // Hash each byte of the 64-bit value
152 for (int i = 0; i < 8; i++) {
153 uint64_t byte = (value >> (i * 8)) & FNV1A_32_MASK;
154 hash = ((hash ^ byte) * FNV1A_32_PRIME) & FNV1A_32_MASK;
155 }
156
157 return (uint32_t)hash;
158}
159
unsigned int uint32_t
Definition common.h:58
unsigned long long uint64_t
Definition common.h:59
#define FNV1A_32_HASH(hash, byte)
FNV-1a 32-bit hash macro for a single byte.
Definition fnv1a.h:51
#define FNV1A_32_OFFSET_BASIS
FNV-1a 32-bit offset basis.
Definition fnv1a.h:35
#define FNV1A_32_MASK
FNV-1a 32-bit mask.
Definition fnv1a.h:41
#define FNV1A_32_PRIME
FNV-1a 32-bit prime.
Definition fnv1a.h:38