package freenet.support.math; import freenet.support.Fields; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import junit.framework.*; public class MersenneTwisterTest extends TestCase { // Should be sufficient for testing MT private static final int SEED_SIZE = 624; private static final int[] INT_SEED = new int[SEED_SIZE]; private static final byte[] BYTE_SEED; static { ByteBuffer bb = ByteBuffer.allocate(INT_SEED.length*4); for(int i=0; i<INT_SEED.length; i++){ INT_SEED[i] = i; bb.putInt(i); } BYTE_SEED = bb.array(); } private static final int[] INPUT_1 = new int[] { 123456789, 123456789, 123456789, 123456789 }; private static final byte[] OUTPUT_1 = new byte[] { (byte)0x15, (byte)0xCD, (byte)0x5B, (byte)0x7, (byte)0x15, (byte)0xCD, (byte)0x5B, (byte)0x7, (byte)0x15, (byte)0xCD, (byte)0x5B, (byte)0x7, (byte)0x15, (byte)0xCD, (byte)0x5B, (byte)0x7 }; private static final byte[] EXPECTED_OUTPUT_MT_INT = new byte[] { (byte)0x9a, (byte)0x6, (byte)0xab, (byte)0x8c, (byte)0x2b, (byte)0xf3, (byte)0x3d, (byte)0x7f, (byte)0x6, (byte)0x4, (byte)0x5b, (byte)0x20ac, (byte)0x46, (byte)0xdd, (byte)0xdf, (byte)0x47, (byte)0x28, (byte)0xc0, (byte)0xb7, (byte)0x74 }; private static final byte[] EXPECTED_OUTPUT_MT_LONG = new byte[] { (byte)0x4f, (byte)0x75, (byte)0xda, (byte)0x52, (byte)0xe2, (byte)0x40, (byte)0xf0, (byte)0x1, (byte)0x8a, (byte)0x69, (byte)0xf6, (byte)0xcb, (byte)0x1a, (byte)0xe3, (byte)0x1, (byte)0xb6, (byte)0x21, (byte)0x1f, (byte)0x73, (byte)0xec }; private static final byte[] EXPECTED_OUTPUT_MT_INTS = new byte[] { (byte)0x1C, (byte)0x58, (byte)0xB0, (byte)0x47, (byte)0x92, (byte)0xC7, (byte)0xBE, (byte)0xC4, (byte)0x25, (byte)0x64, (byte)0x31, (byte)0x27, (byte)0x12, (byte)0x14, (byte)0xDB, (byte)0xF, (byte)0x61, (byte)0xA6, (byte)0x73, (byte)0x32 }; private static final byte[] EXPECTED_OUTPUT_MT_BYTES = new byte[] { (byte)0x5C, (byte)0x6, (byte)0xAD, (byte)0x71, (byte)0x56, (byte)0xDB, (byte)0xBE, (byte)0x69, (byte)0x87, (byte)0xDF, (byte)0xC4, (byte)0x3B, (byte)0xCB, (byte)0x71, (byte)0x73, (byte)0xF1, (byte)0x9B, (byte)0xED, (byte)0x9, (byte)0x2D, }; public void testBytesToInts() { // Test the consistency in order to avoid the freenet-ext #24 fiasco int[] output = Fields.bytesToInts(OUTPUT_1, 0, OUTPUT_1.length); assertEquals(INPUT_1.length, output.length); for(int i=0; i<INPUT_1.length; i++) assertEquals(INPUT_1[i], output[i]); } public void testConsistencySeedFromInts() throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); MersenneTwister mt = new MersenneTwister(INT_SEED); byte[] bytes = new byte[SEED_SIZE]; mt.nextBytes(bytes); md.update(bytes); assertEquals(new String(EXPECTED_OUTPUT_MT_INTS, "UTF-8"), new String(md.digest(), "UTF-8")); } public void testConsistencySeedFromBytes() throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); MersenneTwister mt = new MersenneTwister(BYTE_SEED); byte[] bytes = new byte[SEED_SIZE]; mt.nextBytes(bytes); md.update(bytes); assertEquals(new String(EXPECTED_OUTPUT_MT_BYTES, "UTF-8"), new String(md.digest(), "UTF-8")); } public void testConsistencySeedFromInteger() throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); MersenneTwister mt = new MersenneTwister(Integer.MAX_VALUE); byte[] bytes = new byte[SEED_SIZE]; mt.nextBytes(bytes); md.update(bytes); assertEquals(new String(EXPECTED_OUTPUT_MT_INT, "UTF-8"), new String(md.digest(), "UTF-8")); } public void testConsistencySeedFromLong() throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); MersenneTwister mt = new MersenneTwister(Long.MAX_VALUE); byte[] bytes = new byte[SEED_SIZE]; mt.nextBytes(bytes); md.update(bytes); assertEquals(new String(EXPECTED_OUTPUT_MT_LONG, "UTF-8"), new String(md.digest(), "UTF-8")); } }