#include "StateChecksum.h" #include void Hasher::appendBytes(const void* data, std::size_t byteCount) { const unsigned char* bytes = static_cast(data); for (std::size_t i = 0; i < byteCount; ++i) { m_state ^= bytes[i]; m_state *= 1099511628211ull; // FNV-1a 64-bit prime } } void Hasher::append(float value) { // Normalize -0.0f to +0.0f so the two equal values share a fingerprint. if (value == 0.0f) { value = 0.0f; } appendBytes(&value, sizeof(value)); } void Hasher::append(double value) { if (value == 0.0) { value = 0.0; } appendBytes(&value, sizeof(value)); } void Hasher::append(const QPoint& point) { const int coords[2] = { point.x(), point.y() }; appendBytes(coords, sizeof(coords)); } void Hasher::append(const QPointF& point) { append(point.x()); append(point.y()); } void Hasher::append(const QVector2D& vector) { append(vector.x()); append(vector.y()); } void Hasher::append(const std::string& text) { appendBytes(text.data(), text.size()); // Length terminator so "ab"+"c" and "a"+"bc" do not collide. const std::size_t length = text.size(); appendBytes(&length, sizeof(length)); } std::uint64_t fingerprintRng(const std::mt19937& rng) { std::ostringstream stream; stream << rng; // full internal state as space-separated integers Hasher hasher; hasher.append(stream.str()); return hasher.getValue(); }