Skip to content

Instantly share code, notes, and snippets.

@RHavar
Created August 7, 2020 00:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RHavar/de670ed9568349f199d2fb3c03f423a6 to your computer and use it in GitHub Desktop.
Save RHavar/de670ed9568349f199d2fb3c03f423a6 to your computer and use it in GitHub Desktop.
const crypto = require("crypto");
const terminatingHash =
"86728f5fc3bd99db94d3cdaf105d67788194e9701bf95d049ad0e1ee3d004277";
const salt = "0000000000000000004d6ec16dafe9d8370958664c1dc422f452892264c59526";
function* genHashChain(hash) {
for (let i = 0; hash !== terminatingHash; i++) {
if (i > 10e6) {
throw new Error("Could not find terminating hash, wrong hash chain?!");
}
yield hash;
hash = crypto.createHash("sha256").update(hash).digest("hex");
}
}
function calcGameId(hash) {
let count = 0;
for (const _ of genHashChain(hash)) {
count++;
if (count > 10e6) {
throw new Error("not part of canonical chain?!");
}
}
return count;
}
function gameResult(seed) {
const nBits = 52; // number of most significant bits to use
const hmac = crypto.createHmac("sha256", salt);
hmac.update(Buffer.from(seed, "hex"));
const r = parseInt(hmac.digest("hex").slice(0, nBits / 4), 16);
let X = r / Math.pow(2, nBits); // uniformly distributed in [0; 1)
X = 99 / (1 - X);
const result = Math.floor(X);
return Math.max(1, result / 100);
}
const seed = process.argv[2];
let gameId = calcGameId(seed);
for (const hash of genHashChain(seed)) {
console.log(
`game id ${(gameId--).toString()} \t ${hash} \t ${gameResult(hash).toFixed(
2
)}x`
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment