TARFS
0.1.5
Read-only TAR filesystem for ESP32
Toggle main menu visibility
Loading...
Searching...
No Matches
hash.c
Go to the documentation of this file.
1
/*
2
* TARFS - Immutable (read-only) filesystem for embedded systems.
3
*
4
* Copyright (c) 2026 Viacheslav Logunov
5
* SPDX-License-Identifier: MMIT
6
*
7
* Author:
8
* Viacheslav Logunov <vvb333007@gmail.com>
9
*
10
* Project:
11
* https://github.com/vvb333007/tarfs
12
*/
13
14
24
25
#include <stdint.h>
26
#include <stddef.h>
27
28
#include "
config.h
"
29
#include "
hash.h
"
30
31
32
#define HASH32_PRIME (uint32_t)(16777619u)
/* Special prime number */
33
40
#define HASH32_PSTEP(hash_, pb_) do { \
41
(hash_) ^= *(const uint8_t *)(pb_++); \
42
(hash_) *= HASH32_PRIME; \
43
} while(0)
44
49
#define HASH32_CSTEP(hash_, b_) do { \
50
(hash_) ^= (uint8_t)(b_); \
51
(hash_) *= HASH32_PRIME; \
52
} while( 0 )
53
54
55
// !! WARNING This macro contains a `return` statement !!
56
//
57
#define HASH32_RETURN_IF_DONE do { if (--len == 0) return hash; } while(0)
58
59
60
61
79
uint32_t
hash32
(uint32_t prev_hash,
const
uint8_t *data,
size_t
len) {
80
81
const
uint32_t *wdata;
/* Pointer to an aligned 32-bit accessible portion of the data */
82
size_t
nwords;
/* Number of 32-bit chunks */
83
uint32_t hash;
/* Resulting hash */
84
uintptr_t addr;
85
86
/* Empty input does not change our hash value */
87
if
(len == 0)
88
return
prev_hash;
89
90
hash = prev_hash;
91
addr = (uintptr_t )data;
92
93
if
(addr & 1) {
94
HASH32_PSTEP
(hash, data);
// advance data pointer
95
HASH32_RETURN_IF_DONE
;
96
}
97
98
if
(addr & 2) {
99
100
HASH32_PSTEP
(hash, data);
// advance data pointer
101
HASH32_RETURN_IF_DONE
;
102
103
HASH32_PSTEP
(hash, data);
// advance data pointer
104
HASH32_RETURN_IF_DONE
;
105
}
106
107
/* At this point we still have data to hash and our data address is 4 bytes aligned
108
* Unrolled version which accesses memory once, reading 4 bytes. Original version does byte-by-byte accesses
109
*
110
*/
111
wdata = (
const
uint32_t *)data;
/* do we break aliasing rules here? gcc is quiet */
112
nwords = len >> 2;
/* number of 32 bit words to hash */
113
114
len &= 3;
/* len now indicates trailing bytes count [0..3] */
115
116
while
(nwords > 0) {
117
118
uint32_t v = *wdata++;
119
120
#if CONFIG_TARFS_BIG_ENDIAN
121
HASH32_CSTEP
(hash, v >> 24);
// advance data pointer
122
HASH32_CSTEP
(hash, v >> 16);
123
HASH32_CSTEP
(hash, v >> 8);
124
HASH32_CSTEP
(hash, v);
125
#else
126
HASH32_CSTEP
(hash, v);
// advance data pointer
127
HASH32_CSTEP
(hash, v >> 8);
128
HASH32_CSTEP
(hash, v >> 16);
129
HASH32_CSTEP
(hash, v >> 24);
130
#endif
131
132
nwords--;
133
}
134
135
/* There may be 1..3 bytes left after fast-path block. Use the same idea
136
* as used in source address alignment procedure, but inverse it
137
*
138
*/
139
data = (
const
uint8_t *)wdata;
140
141
if
(len & 2) {
142
HASH32_PSTEP
(hash, data);
// advance data pointer
143
HASH32_PSTEP
(hash, data);
144
}
145
146
if
(len & 1) {
147
HASH32_PSTEP
(hash, data);
// advance data pointer
148
}
149
150
return
hash;
151
}
152
153
154
155
163
uint64_t
hash64
(uint64_t prev_crc,
void
const
*buffer0,
size_t
buf_len) {
164
165
uint64_t crc = prev_crc;
166
uint8_t
const
*buffer = buffer0;
167
168
while
(buf_len--) {
169
170
crc ^= (uint64_t)*buffer++ << 56;
171
172
for
(
int
i = 0; i < 8; i++) {
173
if
(crc & 0x8000000000000000ULL)
174
crc = (crc << 1) ^ 0x42F0E1EBA9EA3693ULL;
175
else
176
crc <<= 1;
177
}
178
}
179
180
return
crc;
181
}
config.h
HASH32_CSTEP
#define HASH32_CSTEP(hash_, b_)
Same as the above but second arg is the value, not pointer.
Definition
hash.c:49
hash64
uint64_t hash64(uint64_t prev_crc, void const *buffer0, size_t buf_len)
CRC-64/ECMA-182 algoritm.
Definition
hash.c:163
HASH32_RETURN_IF_DONE
#define HASH32_RETURN_IF_DONE
Definition
hash.c:57
HASH32_PSTEP
#define HASH32_PSTEP(hash_, pb_)
Process one byte from pointer (pointer is incremented).
Definition
hash.c:40
hash32
uint32_t hash32(uint32_t prev_hash, const uint8_t *data, size_t len)
Compute FNV-1a hash over a byte buffer.
Definition
hash.c:79
hash.h
src
hash.c
Generated by
1.17.0