29 lines
1.2 KiB
Java
29 lines
1.2 KiB
Java
package com.projectsacrifice.game;
|
|
|
|
import java.security.MessageDigest;
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
/** Stable compact fingerprint for exact deterministic replay comparisons. */
|
|
public final class ReplayStateSignature {
|
|
private ReplayStateSignature() {}
|
|
|
|
public static String of(byte[] puzzleState, boolean completed, boolean allDoorsOpen) {
|
|
if (puzzleState == null) throw new IllegalArgumentException("Puzzle state is required");
|
|
try {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
digest.update((byte) (completed ? 1 : 0));
|
|
digest.update((byte) (allDoorsOpen ? 1 : 0));
|
|
digest.update(puzzleState);
|
|
byte[] bytes = digest.digest();
|
|
StringBuilder hex = new StringBuilder(32);
|
|
for (int i = 0; i < 16; i++) {
|
|
hex.append(Character.forDigit((bytes[i] >>> 4) & 0xf, 16));
|
|
hex.append(Character.forDigit(bytes[i] & 0xf, 16));
|
|
}
|
|
return hex.toString();
|
|
} catch (NoSuchAlgorithmException impossible) {
|
|
throw new IllegalStateException("SHA-256 unavailable", impossible);
|
|
}
|
|
}
|
|
}
|