translationSourceHash function
A short, stable, platform-independent hash of source, rendered as 16 hex
characters.
Determinism is the whole point — the value must be identical across app
launches, Dart/SDK versions, and platforms (native and web), otherwise
the same copy would resolve to different storage keys on different devices.
It is therefore computed with plain integer arithmetic kept below 2^53 so
it is exact on the web (where int is a JS double) rather than relying on
String.hashCode (per-run/unstable) or 64-bit bitwise ops (lossy on web).
Two 31-bit polynomial hashes evaluated at different multipliers are
combined for ~62 bits of space. The multipliers must differ — with a
shared multiplier and only different seeds, h2 - h1 collapses to a
length-only constant, so equal-length strings that collide in one half
collide in both and the effective strength drops to ~31 bits. Collisions
only matter between differing source strings under the same key, so this
is comfortably collision-resistant for the purpose.
Do not change this algorithm. Stored <key>@@<hash> entries in every
consumer database are addressed by it; changing it orphans them all. It is
pinned by a golden test.
Implementation
String translationSourceHash(String source) {
final bytes = utf8.encode(source);
final h1 = _polyHash(bytes, 5381, 1000003);
final h2 = _polyHash(bytes, 52711, 1000033);
final s1 = h1.toRadixString(16).padLeft(8, '0');
final s2 = h2.toRadixString(16).padLeft(8, '0');
return '$s1$s2';
}