60 lines
1.8 KiB
C++
60 lines
1.8 KiB
C++
#include "MetaCoreFoundation/MetaCoreHash.h"
|
|
|
|
#include <array>
|
|
#include <fstream>
|
|
|
|
namespace MetaCore {
|
|
|
|
namespace {
|
|
|
|
constexpr std::uint64_t GMetaCoreFnvOffsetBasis = 1469598103934665603ULL;
|
|
constexpr std::uint64_t GMetaCoreFnvPrime = 1099511628211ULL;
|
|
|
|
} // namespace
|
|
|
|
std::uint64_t MetaCoreHashBytes(std::span<const std::byte> data) {
|
|
std::uint64_t hashValue = GMetaCoreFnvOffsetBasis;
|
|
for (std::byte byteValue : data) {
|
|
hashValue ^= static_cast<std::uint64_t>(std::to_integer<unsigned char>(byteValue));
|
|
hashValue *= GMetaCoreFnvPrime;
|
|
}
|
|
return hashValue;
|
|
}
|
|
|
|
std::uint64_t MetaCoreHashString(std::string_view value) {
|
|
const auto* bytes = reinterpret_cast<const std::byte*>(value.data());
|
|
return MetaCoreHashBytes(std::span(bytes, value.size()));
|
|
}
|
|
|
|
std::optional<std::uint64_t> MetaCoreHashFile(const std::filesystem::path& path) {
|
|
std::ifstream input(path, std::ios::binary);
|
|
if (!input.is_open()) {
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::array<char, 4096> buffer{};
|
|
std::uint64_t hashValue = GMetaCoreFnvOffsetBasis;
|
|
while (input.good()) {
|
|
input.read(buffer.data(), static_cast<std::streamsize>(buffer.size()));
|
|
const std::streamsize readCount = input.gcount();
|
|
if (readCount <= 0) {
|
|
break;
|
|
}
|
|
|
|
const auto* bytes = reinterpret_cast<const std::byte*>(buffer.data());
|
|
for (std::streamsize index = 0; index < readCount; ++index) {
|
|
hashValue ^= static_cast<std::uint64_t>(std::to_integer<unsigned char>(bytes[index]));
|
|
hashValue *= GMetaCoreFnvPrime;
|
|
}
|
|
}
|
|
|
|
return hashValue;
|
|
}
|
|
|
|
std::uint64_t MetaCoreHashCombine(std::uint64_t seed, std::uint64_t value) {
|
|
seed ^= value + 0x9E3779B97F4A7C15ULL + (seed << 6U) + (seed >> 2U);
|
|
return seed;
|
|
}
|
|
|
|
} // namespace MetaCore
|