/*
* Copyright 2013 Thomas Bocek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package net.tomp2p.peers;
import java.math.BigInteger;
import java.util.Random;
import java.util.concurrent.ConcurrentSkipListSet;
import org.junit.Assert;
import org.junit.Test;
public class TestNumber160 {
private final Random rnd = new Random();
@Test
public void testLength() {
Number160 bi1 = new Number160("0x7f");
Number160 bi2 = new Number160("0x80");
Number160 bi3 = new Number160("0xff");
Assert.assertEquals(false, bi1.compareTo(bi2) == 0);
Assert.assertEquals(bi3, PeerMap.distance(bi1, bi2));
Assert.assertEquals(7, PeerMap.classMember(bi1, bi2));
Assert.assertEquals(6, PeerMap.classMember(bi2, bi3));
}
@Test
public void testXor() {
BigInteger bi1 = new BigInteger("1234567890abcdef1234567890abcdef12345678", 16);
Number160 ki1 = new Number160("0x1234567890abcdef1234567890abcdef12345678");
BigInteger bi2 = new BigInteger("357116889007843534245232322114545905234a", 16);
Number160 ki2 = new Number160("0x357116889007843534245232322114545905234a");
Assert.assertEquals("0x" + bi1.toString(16), ki1.toString(true));
Assert.assertEquals("0x" + bi2.toString(16), ki2.toString(true));
Number160 ki3 = ki1.xor(ki2);
BigInteger bi3 = bi1.xor(bi2);
Assert.assertEquals("0x" + bi3.toString(16), ki3.toString(true));
}
@Test
public void testRandomXor() {
for (int i = 0; i < 1000; i++) {
BigInteger bi1 = new BigInteger(160, rnd);
BigInteger bi2 = new BigInteger(160, rnd);
if (bi1.toString(16).length() == 40 && bi2.toString(16).length() == 40) {
Number160 ki1 = new Number160("0x" + bi1.toString(16));
Number160 ki2 = new Number160("0x" + bi2.toString(16));
//
Number160 ki3 = ki1.xor(ki2);
BigInteger bi3 = bi1.xor(bi2);
Assert.assertEquals(ki3.toString(true), "0x" + bi3.toString(16));
}
}
}
@Test
public void testFromIntArray() {
int[] tmp = new int[] { 1, 2, 3, 4, 5 };
Number160 ki2 = new Number160(tmp);
Assert.assertEquals("0x0000000100000002000000030000000400000005", ki2.toString(false));
tmp = new int[] { -1, -1, -1, -1, -1 };
ki2 = new Number160(tmp);
Assert.assertEquals("0xffffffffffffffffffffffffffffffffffffffff", ki2.toString(false));
ki2 = new Number160(new int[] { 1, 2 });
Assert.assertEquals("0x100000002", ki2.toString());
ki2 = new Number160(new int[] { 1 });
Assert.assertEquals("0x1", ki2.toString());
ki2 = new Number160(new int[] { 1, 1, 1, 1, 1 });
Assert.assertEquals("0x0000000100000001000000010000000100000001", ki2.toString(false));
}
@Test
public void testFromString() {
Number160 ki2 = new Number160("0x9");
Assert.assertEquals("0x9", ki2.toString(true));
ki2 = new Number160("0x22");
Assert.assertEquals("0x22", ki2.toString(true));
ki2 = new Number160("0x0000000000000002000000030000000400000005");
Assert.assertEquals("0x2000000030000000400000005", ki2.toString(true));
Assert.assertEquals("0x0000000000000002000000030000000400000005", ki2.toString(false));
ki2 = new Number160("0x0400000005");
Assert.assertEquals("0x400000005", ki2.toString(true));
ki2 = new Number160("0x0000000000000002000000000000000000000000");
Assert.assertEquals("0x2000000000000000000000000", ki2.toString(true));
Assert.assertEquals("0x0000000000000002000000000000000000000000", ki2.toString(false));
ki2 = new Number160("0x1000000000000000000000000000000000000000");
Assert.assertEquals("0x1000000000000000000000000000000000000000", ki2.toString(true));
ki2 = new Number160("0x100000000000000000000");
Assert.assertEquals("0x100000000000000000000", ki2.toString(true));
}
@Test
public void testFromInt() {
Number160 ki2 = new Number160(0x2c);
Assert.assertEquals("0x2c", ki2.toString());
}
@Test
public void testFromByteArray() {
Number160 ki2 = new Number160(new byte[] { 1 });
Assert.assertEquals("0x1", ki2.toString());
ki2 = new Number160(1, 2);
Assert.assertEquals("0x100000002", ki2.toString());
ki2 = new Number160(new byte[] { 1, 2 });
Assert.assertEquals("0x102", ki2.toString());
//
ki2 = new Number160(new byte[] { 1 });
Number160 ki3 = new Number160(new byte[] { 2 });
Assert.assertEquals(true, ki2.compareTo(ki3) < 0);
//
ki2 = new Number160(new byte[] { 3 });
ki3 = new Number160(new byte[] { 2 });
Assert.assertEquals(true, ki2.compareTo(ki3) > 0);
//
ki2 = new Number160(new byte[] { 3 });
ki3 = new Number160(new byte[] { 3 });
Assert.assertEquals(true, ki2.compareTo(ki3) == 0);
//
ki2 = new Number160(new byte[] { 2, 3 });
ki3 = new Number160(new byte[] { 3, 2 });
Assert.assertEquals(true, ki2.compareTo(ki3) < 0);
//
ki2 = new Number160(new byte[] { 1, 2, 3 });
ki3 = new Number160(new byte[] { 3, 2 });
Assert.assertEquals(true, ki2.compareTo(ki3) > 0);
}
@Test
public void testSerialization() {
Number160 ki2 = new Number160("0x357116889007843534245232322114545905234a");
byte[] me = ki2.toByteArray();
Number160 ki3 = new Number160(me);
Assert.assertEquals(ki2, ki3);
//
ki2 = Number160.MAX_VALUE;
me = ki2.toByteArray();
ki3 = new Number160(me);
Assert.assertEquals(ki2, ki3);
//
ki2 = new Number160("0x1234567890abcdef1234567890abcdef12345678");
me = ki2.toByteArray();
ki3 = new Number160(me);
Assert.assertEquals(ki2, ki3);
}
@Test
public void testIsZero() {
Number160 ki2 = new Number160(new byte[] { 0 });
Number160 ki3 = new Number160(new byte[] { 2 });
Assert.assertEquals(true, ki2.isZero());
Assert.assertEquals(false, ki3.isZero());
}
@Test
public void testBitLength() {
Number160 ki2 = Number160.ONE;
Assert.assertEquals(1, ki2.bitLength());
ki2 = new Number160("0x2");
Assert.assertEquals(2, ki2.bitLength());
ki2 = new Number160("0x3");
Assert.assertEquals(2, ki2.bitLength());
ki2 = new Number160("0xfa");
Assert.assertEquals(8, ki2.bitLength());
ki2 = new Number160("0x100000002");
Assert.assertEquals(33, ki2.bitLength());
ki2 = new Number160("0x1100000002");
Assert.assertEquals(37, ki2.bitLength());
try {
ki2 = new Number160("0x-1");
Assert.fail();
} catch (RuntimeException e) {
}
ki2 = Number160.MAX_VALUE;
Assert.assertEquals(160, ki2.bitLength());
}
@Test
public void testDouble() {
BigInteger bi1 = new BigInteger("1234567890abcdef1234567890abcdef12345678", 16);
Number160 ki1 = new Number160("0x1234567890abcdef1234567890abcdef12345678");
BigInteger bi2 = new BigInteger("357116889007843534245232322114545905234a", 16);
Number160 ki2 = new Number160("0x357116889007843534245232322114545905234a");
Assert.assertEquals(0, Double.compare(bi1.doubleValue(), ki1.doubleValue()));
Assert.assertEquals(0, Double.compare(bi2.doubleValue(), ki2.doubleValue()));
}
@Test
public void testFloat() {
BigInteger bi1 = new BigInteger("1234567890abcdef1234567890abcdef12345678", 16);
Number160 ki1 = new Number160("0x1234567890abcdef1234567890abcdef12345678");
BigInteger bi2 = new BigInteger("357116889007843534245232322114545905234a", 16);
Number160 ki2 = new Number160("0x357116889007843534245232322114545905234a");
Assert.assertEquals(0, Float.compare(bi1.floatValue(), ki1.floatValue()));
Assert.assertEquals(0, Float.compare(bi2.floatValue(), ki2.floatValue()));
}
@Test
public void testPerformance() {
int runs = 10000;
BigInteger bi1[] = new BigInteger[runs];
BigInteger bi2[] = new BigInteger[runs];
for (int i = 0; i < runs; i++) {
bi1[i] = new BigInteger(160, rnd);
bi2[i] = new BigInteger(160, rnd);
if (bi1[i].toString(16).length() != 40 || bi2[i].toString(16).length() != 40)
i--;
}
Number160 ki1[] = new Number160[runs];
Number160 ki2[] = new Number160[runs];
for (int i = 0; i < runs; i++) {
ki1[i] = new Number160("0x" + bi1[i].toString(16));
ki2[i] = new Number160("0x" + bi2[i].toString(16));
}
long start = System.currentTimeMillis();
BigInteger bi3 = BigInteger.TEN;
for (int j = 1; j < 1000; j++) {
for (int i = 0; i < runs; i++)
// int i = 0;
bi3 = bi1[(i * j) % runs].xor(bi2[i]).xor(bi3);
}
System.err.println("BigInteger time " + (System.currentTimeMillis() - start) + ", " + bi3.toString(16));
start = System.currentTimeMillis();
Number160 ki3 = new Number160(10);
for (int j = 1; j < 1000; j++) {
for (int i = 0; i < runs; i++)
ki3 = ki1[(i * j) % runs].xor(ki2[i]).xor(ki3);
}
System.err.println("Key time " + (System.currentTimeMillis() - start) + ", " + ki3);
Assert.assertEquals("0x" + bi3.toString(16), ki3.toString());
}
@Test
public void testPerformance2() {
ConcurrentSkipListSet<BigInteger> test1 = new ConcurrentSkipListSet<BigInteger>();
ConcurrentSkipListSet<Number160> test2 = new ConcurrentSkipListSet<Number160>();
int runs = 10000;
BigInteger bi1[] = new BigInteger[runs];
for (int i = 0; i < runs; i++) {
bi1[i] = new BigInteger(160, rnd);
if (bi1[i].toString(16).length() != 40)
i--;
}
Number160 ki1[] = new Number160[runs];
for (int i = 0; i < runs; i++)
ki1[i] = new Number160("0x" + bi1[i].toString(16));
long start = System.currentTimeMillis();
for (int j = 0; j < 500; j++) {
test1.clear();
for (int i = 0; i < runs; i++)
test1.add(bi1[i]);
}
System.err.println("BigInteger time " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int j = 0; j < 500; j++) {
test2.clear();
for (int i = 0; i < runs; i++)
test2.add(ki1[i]);
}
System.err.println("Key time " + (System.currentTimeMillis() - start));
Assert.assertEquals("0x" + test1.first().toString(16), test2.first().toString());
}
@Test
public void testLong() {
Number160 n1 = new Number160(1);
Number160 n2 = new Number160(1L);
Assert.assertEquals(n1, n2);
//
n2 = new Number160(Long.MAX_VALUE);
Assert.assertEquals("0x7FFFFFFFFFFFFFFF".toLowerCase(), n2.toString());
}
}