/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package freenet.support; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; import java.util.BitSet; import junit.framework.TestCase; /** * Test case for {@link freenet.support.HexUtil} class. * * @author Alberto Bacchelli <sback@freenetproject.org> */ public class HexUtilTest extends TestCase { /** * Test the bytesToHex(byte[]) method * against every possible single byte value. */ public void testBytesToHex_byte() { byte[] methodByteArray = new byte[1]; String expectedResult; for (int i = 255; i >= 0; i--) { methodByteArray[0] = (byte)i; /* Integer.toHexString works with int so it doesn't return always a two digit hex. For this reason we need the next "switch case". */ expectedResult = (i <= 15? "0" + (Integer.toHexString(i)): (Integer.toHexString(i))); assertEquals(expectedResult,HexUtil.bytesToHex(methodByteArray));} } /** * Test the hexToBytes(String) method * against the hex representation of * every possible single byte. * The starting offset is always 0. */ public void testHexToBytes_String() { byte[] expectedByteArray = new byte[1]; String methodHexString; for (int i = 255; i >= 0; i--) { expectedByteArray[0] = (byte)i; /* Integer.toHexString works with int so it doesn't return always a two digit hex. For this reason we need the next "switch case". */ methodHexString = (i <= 15? "0" + (Integer.toHexString(i)): (Integer.toHexString(i))); assertTrue(Arrays.equals(expectedByteArray,HexUtil.hexToBytes(methodHexString)));} } /** * Test the hexToBytes(String,int) method * against the hex representation of * every possible single byte. * The starting offset is always 0. */ public void testHexToBytes_StringInt() { byte[] expectedByteArray = new byte[1]; String methodHexString; for (int i = 255; i >= 0; i--) { expectedByteArray[0] = (byte)i; /* Integer.toHexString works with int so it doesn't return always a two digit hex. For this reason we need the next "switch case". */ methodHexString = (i <= 15? "0" + (Integer.toHexString(i)): (Integer.toHexString(i))); assertTrue(Arrays.equals(expectedByteArray,HexUtil.hexToBytes(methodHexString,0)));} } /** * Test the hexToBytes(String,byte[],int) method * against the hex representation of * every possible single byte. */ public void testHexToBytes_StringByteInt() { byte[] expectedByteArray = new byte[1]; byte[] outputArray = new byte[1]; String methodHexString; for (int i = 255; i >= 0; i--) { expectedByteArray[0] = (byte)i; /* Integer.toHexString works with int so it doesn't return always a two digit hex. For this reason we need the next "switch case". */ methodHexString = (i <= 15? "0" + (Integer.toHexString(i)): (Integer.toHexString(i))); HexUtil.hexToBytes(methodHexString,outputArray,0); assertTrue(Arrays.equals(expectedByteArray,outputArray));} } /** * Test the bitsToByte(BitSet,int) method * against the bit representation of * every possible single byte. */ public void testBitsToBytes_BitSetInt() { byte[] expectedByteArray = new byte[1]; byte[] outputArray = new byte[1]; BitSet methodBitSet = new BitSet(8); for (int i = 0; i < 256; i++) { outputArray = HexUtil.bitsToBytes(methodBitSet, 8); expectedByteArray[0] = (byte)i; assertTrue(Arrays.equals(expectedByteArray,outputArray)); addOne(methodBitSet); } } /** * It adds 1 to a given BitSet * @param aBitSet */ private void addOne(BitSet aBitSet) { int bitSetIndex = 0; while (aBitSet.get(bitSetIndex)==true) { aBitSet.flip(bitSetIndex); bitSetIndex++; } aBitSet.flip(bitSetIndex); } /** * Test countBytesForBits(int) method * against all possible values until 256 bytes */ public void testCountBytesForBits_int() { //border case assertEquals(HexUtil.countBytesForBits(0),0); for (int expectedBytesCount = 1; expectedBytesCount < 256; expectedBytesCount++) for (int bits = (expectedBytesCount-1)*8+1; bits <= (expectedBytesCount)*8; bits++) assertEquals(HexUtil.countBytesForBits(bits),expectedBytesCount); } /** * Test bytesToBits(byte[],BitSet,int) method * against all possible single byte value. * It uses HexUtil.bitsToBytes() method for the check, * so be sure that method works correctly! */ public void testBytesToBits_byteBitSetInt() { byte[] methodByteArray = new byte[1]; BitSet methodBitSet = new BitSet(8); for (int i = 0; i < 255; i++) { methodByteArray[0] = (byte)i; HexUtil.bytesToBits(methodByteArray,methodBitSet,7); assertTrue(Arrays.equals(methodByteArray,HexUtil.bitsToBytes(methodBitSet,8)));} } /** * Test biToHex(BigInteger) method * comparing its results to results provided * by different scientific valid calculators. */ public void testBiToHex_BigInteger() { BigInteger methodBigInteger = new BigInteger("999999999999999"); String expectedHexValue = "038d7ea4c67fff"; assertEquals(HexUtil.biToHex(methodBigInteger),expectedHexValue); methodBigInteger = BigInteger.ZERO; expectedHexValue = "00"; assertEquals(HexUtil.biToHex(methodBigInteger),expectedHexValue); methodBigInteger = new BigInteger("72057594037927935"); expectedHexValue = "00ffffffffffffff"; assertEquals(HexUtil.biToHex(methodBigInteger),expectedHexValue); } /** * Test bitsToHexString(BitSet,int) method * comparing its results to results provided * by different scientific valid calculators. */ public void testBitsToHexString() { BitSet methodBitSet = new BitSet(8); String expectedString = "00"; assertEquals(HexUtil.bitsToHexString(methodBitSet,8),expectedString); methodBitSet.set(0,7,true); /*0x7f*/ expectedString = "7f"; assertEquals(HexUtil.bitsToHexString(methodBitSet,8),expectedString); methodBitSet.set(0,9,true); /*0xff*/ expectedString = "ff"; assertEquals(HexUtil.bitsToHexString(methodBitSet,8),expectedString); } /** * Tests hexToBits(String,BitSet,int) method */ public void testHexToBits() { String methodStringToStore = "00"; BitSet methodBitSet = new BitSet(8); HexUtil.hexToBits(methodStringToStore,methodBitSet,methodBitSet.size()); assertTrue(methodBitSet.cardinality()==0); BitSet expectedBitSet = new BitSet(8); expectedBitSet.set(0,7,true); /*0x7f*/ methodStringToStore = "7f"; methodBitSet = new BitSet(8); HexUtil.hexToBits(methodStringToStore,methodBitSet,methodBitSet.size()); assertTrue(methodBitSet.intersects(expectedBitSet)); expectedBitSet.set(0,9,true); /*0xff*/ methodStringToStore = "ff"; methodBitSet = new BitSet(8); HexUtil.hexToBits(methodStringToStore,methodBitSet,methodBitSet.size()); assertTrue(methodBitSet.intersects(expectedBitSet)); } /** * Tests writeBigInteger(BigInteger,DataOutputStream) * and readBigInteger(DataInputStream) comparing a * BigInteger after writing it to a Stream and * reading it from the writing result. */ public void testWriteAndReadBigInteger() { BigInteger methodBigInteger = new BigInteger("999999999999999"); ByteArrayOutputStream methodByteArrayOutStream = new ByteArrayOutputStream(); DataOutputStream methodDataOutStream = new DataOutputStream(methodByteArrayOutStream); try { HexUtil.writeBigInteger(methodBigInteger,methodDataOutStream); ByteArrayInputStream methodByteArrayInStream = new ByteArrayInputStream(methodByteArrayOutStream.toByteArray()); DataInputStream methodDataInStream = new DataInputStream(methodByteArrayInStream); assertTrue(methodBigInteger.compareTo(HexUtil.readBigInteger(methodDataInStream))==0); } catch (IOException aException) { fail("Not expected exception thrown : " + aException.getMessage()); } } /** * Test bytesToHex(byte[],int,int) method * with a too long starting offset. The tested * method should raise an exception. */ public void testBytesToHex_byteIntInt_WithLongOffset() { try { int arrayLength = 3; byte[] methodBytesArray = new byte[arrayLength]; HexUtil.bytesToHex(methodBytesArray,arrayLength+1,1); fail("Expected Exception Error Not Thrown!"); } catch (IllegalArgumentException anException) { assertNotNull(anException); } } /** * Test bytesToHex(byte[],int,int) method * with asking to read too many bytes. The tested * method should raise an exception. */ public void testBytesToHex_byteIntInt_WithLongReading() { try { int arrayLength = 3; byte[] methodBytesArray = new byte[arrayLength]; HexUtil.bytesToHex(methodBytesArray,0,arrayLength+1); fail("Expected Exception Error Not Thrown!"); } catch (IllegalArgumentException anException) { assertNotNull(anException); } } /** * Test bytesToHex(byte[],int,int) method * with a 0 length. */ public void testBytesToHex_byteIntInt_WithZeroLength() { int length = 0; byte[] methodBytesArray = {1,2,3}; //a non-zero bytes array assertEquals("",HexUtil.bytesToHex(methodBytesArray,0,length)); } /** * Test hexToBytes(String,byte[],int) method * with a too long offset. * The method should raise an exception. */ public void testHexToBytes_StringByteInt_WithLongOffset() { try { String methodString = "0"; byte[] methodByteArray = new byte[1]; HexUtil.hexToBytes(methodString,methodByteArray,methodByteArray.length); fail("Expected Exception Error Not Thrown!"); } catch (ArrayIndexOutOfBoundsException anException) { assertNotNull(anException); } } /** * Test hexToBytes(String,byte[],int) method * with a too short byte[] to put the result. * The method should raise an exception. */ public void testHexToBytes_StringByteInt_WithShortArray() { try { String methodString = "0000"; byte[] methodByteArray = new byte[1]; HexUtil.hexToBytes(methodString,methodByteArray,0); fail("Expected Exception Error Not Thrown!"); } catch (IndexOutOfBoundsException anException) { assertNotNull(anException); } } /** * Test all hexToBytes() methods * with a not valid character. * The method should raise an exception. */ public void testHexToBytes_WithBadDigit() { String methodString = "00%0"; try { byte[] methodByteArray = new byte[methodString.length()]; HexUtil.hexToBytes(methodString,methodByteArray,0); fail("Expected Exception Error Not Thrown!"); } catch (NumberFormatException anException) { assertNotNull(anException); } try { HexUtil.hexToBytes(methodString,0); fail("Expected Exception Error Not Thrown!"); } catch (NumberFormatException anException) { assertNotNull(anException); } try { HexUtil.hexToBytes(methodString); fail("Expected Exception Error Not Thrown!"); } catch (NumberFormatException anException) { assertNotNull(anException); } } /** * Test the bitsToByte(BitSet,int) method * using a size smaller than the actual number * of bits in the BitSet. */ public void testBitsToBytes_WithShortSize() { byte[] expectedByteArray = new byte[1]; byte[] outputArray = new byte[1]; BitSet methodBitSet = new BitSet(8); /* 0x01 */ methodBitSet.flip(0); expectedByteArray[0] = (byte)1; /* 0x01 & 0x00 == 0x01 */ outputArray = HexUtil.bitsToBytes(methodBitSet,0); assertFalse(Arrays.equals(expectedByteArray,outputArray)); /* 0x01 & 0x01 == 0x01 */ outputArray = HexUtil.bitsToBytes(methodBitSet,1); assertTrue(Arrays.equals(expectedByteArray,outputArray)); /* 0x80 */ methodBitSet.flip(7); /* 0x08 */ methodBitSet.flip(3); expectedByteArray[0] = (byte)128+8+1; /* 0x89 & 0x08 == 0x89 */ outputArray = HexUtil.bitsToBytes(methodBitSet,3); assertFalse(Arrays.equals(expectedByteArray,outputArray)); /* 0x89 & 0xff == 0x89 */ outputArray = HexUtil.bitsToBytes(methodBitSet,8); assertTrue(Arrays.equals(expectedByteArray,outputArray)); } /* Checks that offset == array length is allowed, which is needed for * handling zero length arrays */ public void testBytesToHexZeroLength() { assertEquals("", HexUtil.bytesToHex(new byte[0], 0, 0)); assertEquals("", HexUtil.bytesToHex(new byte[2], 2, 0)); } }