Files
dota_factory/src/lib/sim/StateChecksum.cpp

62 lines
1.4 KiB
C++

#include "StateChecksum.h"
#include <sstream>
void Hasher::appendBytes(const void* data, std::size_t byteCount)
{
const unsigned char* bytes = static_cast<const unsigned char*>(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();
}