18 static constexpr char alphabet[] =
"0123456789abcdef";
19 std::string hex(32,
'\0');
20 const std::array<uint64_t, 2> parts = {hash.
high64, hash.
low64};
22 for(
const auto part : parts)
24 for(
int shift = 60; shift >= 0; shift -= 4)
26 hex[offset++] = alphabet[(part >> shift) & 0xF];
39 auto parse_nibble = [](
char c) -> uint64_t
41 if(c >=
'0' && c <=
'9')
43 return static_cast<uint64_t
>(c -
'0');
45 if(c >=
'a' && c <=
'f')
47 return static_cast<uint64_t
>(10 + c -
'a');
49 if(c >=
'A' && c <=
'F')
51 return static_cast<uint64_t
>(10 + c -
'A');
55 for(
size_t i = 0; i < 16; ++i)
59 for(
size_t i = 16; i < 32; ++i)
61 hash.
low64 = (hash.
low64 << 4) | parse_nibble(hex[i]);
67 const unsigned char* data,
71 auto feed = [&](
const unsigned char* ptr,
size_t len)
80 static const unsigned char lf =
'\n';
88 const unsigned char c = data[
index++];
126 const unsigned char c = data[
index++];
138auto hash_mapped_fingerprint(
const char* data,
size_t size,
bool normalize_text_line_endings) -> std::string
140 if(normalize_text_line_endings)
144 bool last_was_cr =
false;
145 xxh3_update_text_normalized(state,
reinterpret_cast<const unsigned char*
>(data),
size, last_was_cr);
148 static const unsigned char lf =
'\n';
156auto hash_stream_fingerprint(std::istream& file,
bool normalize_text_line_endings) -> std::string
158 std::vector<char> buffer(64 * 1024);
159 if(normalize_text_line_endings)
163 bool last_was_cr =
false;
166 file.read(buffer.data(),
static_cast<std::streamsize
>(buffer.size()));
167 const std::streamsize bytes_read = file.gcount();
172 xxh3_update_text_normalized(state,
173 reinterpret_cast<const unsigned char*
>(buffer.data()),
174 static_cast<size_t>(bytes_read),
179 static const unsigned char lf =
'\n';
188 file.read(buffer.data(),
static_cast<std::streamsize
>(buffer.size()));
189 const std::streamsize bytes_read = file.gcount();
203 file_istream input(file_path, normalize_text_line_endings ? std::ios::in : std::ios::binary);
208 return hash_stream_fingerprint(
input, normalize_text_line_endings);
212 const std::string* additional_fingerprints,
213 size_t additional_count) -> std::string
217 if(!first_fingerprint.empty())
219 const XXH128_hash_t first_hash = hex_to_xxh128(first_fingerprint);
222 for(
size_t i = 0; i < additional_count; ++i)
224 const XXH128_hash_t hash = hex_to_xxh128(additional_fingerprints[i]);
stdio-backed input stream. Accepts std::ios open flags (e.g. std::ios::binary) when opening a
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t *statePtr)
Resets an XXH3_state_t to begin a new hash.
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest(XXH_NOESCAPE const XXH3_state_t *statePtr)
Returns the calculated XXH3 128-bit hash value from an XXH3_state_t.
struct XXH3_state_s XXH3_state_t
The opaque state struct for the XXH3 streaming API.
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void *data, size_t len)
Calculates 128-bit unseeded variant of XXH3 of data.
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH_NOESCAPE XXH3_state_t *statePtr, XXH_NOESCAPE const void *input, size_t length)
Consumes a block of input to an XXH3_state_t.
auto hash_file_fingerprint(const path &file_path, bool normalize_text_line_endings) -> std::string
Hash a file's contents. Text assets normalize CRLF to LF before hashing.
auto combine_file_fingerprints(const std::string &first_fingerprint, const std::string *additional_fingerprints, size_t additional_count) -> std::string
Combine per-file fingerprints (raw 128-bit digests) into one hex fingerprint.
std::vector< math::vec3 > start
The return value from 128-bit hashes.