41 lines
1.0 KiB
C++
41 lines
1.0 KiB
C++
#include "fgc/Hash.h"
|
|
|
|
#include <cstdio>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
|
|
namespace fgc {
|
|
|
|
namespace {
|
|
constexpr uint64_t kOffsetBasis = 0xcbf29ce484222325ULL;
|
|
constexpr uint64_t kPrime = 0x00000100000001b3ULL;
|
|
} // namespace
|
|
|
|
uint64_t fnv1a64(const std::string& data) {
|
|
uint64_t h = kOffsetBasis;
|
|
for (unsigned char c : data) {
|
|
h ^= c;
|
|
h *= kPrime;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
std::string hashLabel(uint64_t digest) {
|
|
char buf[32];
|
|
std::snprintf(buf, sizeof(buf), "fnv1a64:%016llx", static_cast<unsigned long long>(digest));
|
|
return buf;
|
|
}
|
|
|
|
uint64_t fnv1a64File(const std::string& path) {
|
|
// Binary: the digest must not depend on how the platform treats line endings,
|
|
// or a file copied between machines would look changed when it is not.
|
|
std::ifstream in(path, std::ios::binary);
|
|
if (!in) throw std::runtime_error("cannot read file for hashing: " + path);
|
|
std::ostringstream ss;
|
|
ss << in.rdbuf();
|
|
return fnv1a64(ss.str());
|
|
}
|
|
|
|
} // namespace fgc
|