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); } } }