import org.bouncycastle.jcajce.provider.digest.SHA3;

import java.lang.reflect.Field;
import java.security.SecureRandom;

public class Sha1Debug {
    public static void main(String[] args) throws Exception {
        byte[] fullSeed = new byte[64];
        for (int i = 0; i < 64; i++) fullSeed[i] = (byte) i;
        SHA3.Digest256 d = new SHA3.Digest256();
        byte[] sha3Seed = d.digest(fullSeed);

        SecureRandom rng = SecureRandom.getInstance("SHA1PRNG");
        rng.setSeed(sha3Seed);

        for (int n = 0; n < 3; n++) {
            byte[] out = new byte[20];
            rng.nextBytes(out);
            System.out.println("block" + n + "=" + hex(out));
            dumpState(rng);
        }

        SecureRandom rng2 = SecureRandom.getInstance("SHA1PRNG");
        rng2.setSeed(sha3Seed);
        byte[] out32 = new byte[32];
        rng2.nextBytes(out32);
        System.out.println("out32=" + hex(out32));
    }

    private static void dumpState(SecureRandom rng) {
        try {
            Object spi = getField(rng, "secureRandomSpi");
            if (spi == null) spi = getField(rng, "spi");
            Object target = spi != null ? spi : rng;
            // try common field names
            for (String name : new String[]{"state", "seed", "digest"}) {
                Object v = getField(target, name);
                if (v instanceof byte[]) System.out.println("  " + name + "=" + hex((byte[]) v));
            }
            // dig into SecureRandomSpi implementation
            Class<?> c = target.getClass();
            System.out.println("  spiClass=" + c.getName());
            for (Field f : c.getDeclaredFields()) {
                f.setAccessible(true);
                Object v = f.get(target);
                if (v instanceof byte[]) System.out.println("  f." + f.getName() + "=" + hex((byte[]) v));
            }
        } catch (Exception e) {
            System.out.println("  dump err: " + e);
        }
    }

    private static Object getField(Object obj, String name) {
        Class<?> c = obj.getClass();
        while (c != null) {
            try {
                Field f = c.getDeclaredField(name);
                f.setAccessible(true);
                return f.get(obj);
            } catch (Exception ignored) {
                c = c.getSuperclass();
            }
        }
        return null;
    }

    private static String hex(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (byte x : b) sb.append(String.format("%02x", x));
        return sb.toString();
    }
}
