/*
* $Id$
*
* Copyright 2006, The jCoderZ.org Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of the jCoderZ.org Project nor the names of
* its contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jcoderz.commons.util;
import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
import org.jcoderz.commons.ArgumentMalformedException;
/**
* JUnit Test for the class {@link org.jcoderz.commons.util.Base64Util}.
*
* @author Andreas Mandel
* @author Michael Griffel
*/
public class Base64UtilTest
extends TestCase
{
private static final int TESTDATA_LENGTH = 4097;
private static final byte[] TESTDATA;
private static final String TEST_BASE_64_ENCODED_1 = "dGVzdA==";
private static final String TEST_BASE_64_DECODED_1 = "test";
private static final String TEST_BASE_64_ENCODED_2
= "VGhpcyBpcyBhIGxvbmcgdGVzdCBtZXNzYWdlLiBVc2VkIHRvIHRlc3QgdGhlIHRl"
+ "c3Qu";
private static final String TEST_BASE_64_DECODED_2
= "This is a long test message. Used to test the test.";
private static final int PERFORMANCE_LOOP_COUNT = 10000;
static
{
TESTDATA = new byte[TESTDATA_LENGTH];
new Random().nextBytes(TESTDATA);
}
/** Test short string. */
public void testString1 ()
{
assertEquals("Short test string.", TEST_BASE_64_DECODED_1,
StringUtil.asciiToString(
Base64Util.decode(TEST_BASE_64_ENCODED_1)));
}
/** Test long string. */
public void testString2 ()
{
assertEquals("Long test string.", TEST_BASE_64_DECODED_2,
StringUtil.asciiToString(
Base64Util.decode(TEST_BASE_64_ENCODED_2)));
}
/** Test encode decode sequence. */
public void testEncodeDecodeBinary ()
{
checkEncodeDecode(TESTDATA);
byte[] testdata;
testdata = new byte[TESTDATA.length - 1];
System.arraycopy(TESTDATA, 0, testdata, 0, testdata.length);
checkEncodeDecode(testdata);
testdata = new byte[testdata.length - 1];
System.arraycopy(TESTDATA, 0, testdata, 0, testdata.length);
checkEncodeDecode(testdata);
testdata = new byte[testdata.length - 1];
System.arraycopy(TESTDATA, 0, testdata, 0, testdata.length);
checkEncodeDecode(testdata);
testdata = new byte[testdata.length - 1];
System.arraycopy(TESTDATA, 0, testdata, 0, testdata.length);
checkEncodeDecode(testdata);
testdata = new byte[testdata.length - 1];
System.arraycopy(TESTDATA, 0, testdata, 0, testdata.length);
checkEncodeDecode(testdata);
}
/**
* Encoding performance test.
*/
public void xxxtestEncodePerformanceRef ()
{
final long start = System.currentTimeMillis();
for (int i = 0; i < PERFORMANCE_LOOP_COUNT; ++i)
{
// TOOD: ref impl: Base64.encodeToString(TESTDATA, false);
}
final long diff = System.currentTimeMillis() - start;
System.out.println("Base64 encoding (ref) "
+ (PERFORMANCE_LOOP_COUNT * TESTDATA.length) / diff + "kB/sec");
}
/**
* Encoding performance test.
*/
public void xxxtestEncodePerformance ()
{
final long start = System.currentTimeMillis();
for (int i = 0; i < PERFORMANCE_LOOP_COUNT; ++i)
{
Base64Util.encode(TESTDATA);
}
final long diff = System.currentTimeMillis() - start;
System.out.println("Base64 encoding (enc) "
+ (PERFORMANCE_LOOP_COUNT * TESTDATA.length) / diff + "kB/sec");
}
/**
* Encoding performance test.
*/
public void xxxtestEncodePerformanceRef2 ()
{
final long start = System.currentTimeMillis();
for (int i = 0; i < PERFORMANCE_LOOP_COUNT; ++i)
{
// TOOD: ref impl: Base64.encodeToString(TESTDATA, false);
}
final long diff = System.currentTimeMillis() - start;
System.out.println("Base64 encoding (ref2) "
+ (PERFORMANCE_LOOP_COUNT * TESTDATA.length) / diff + "kB/sec");
}
/**
* Encoding performance test.
*/
public void xxxtestEncodePerformance2 ()
{
final long start = System.currentTimeMillis();
for (int i = 0; i < PERFORMANCE_LOOP_COUNT; ++i)
{
Base64Util.encode(TESTDATA);
}
final long diff = System.currentTimeMillis() - start;
System.out.println("Base64 encoding (enc2) "
+ (PERFORMANCE_LOOP_COUNT * TESTDATA.length) / diff + "kB/sec");
}
/**
* Decoding performance test.
*/
public void xxxtestDecodePerformance ()
{
final long start = System.currentTimeMillis();
final String TEST_ENCODE = Base64Util.encode(TESTDATA);
for (int i = 0; i < PERFORMANCE_LOOP_COUNT; ++i)
{
Base64Util.decode(TEST_ENCODE);
}
final long diff = System.currentTimeMillis() - start;
System.out.println("Base64 decoding "
+ (PERFORMANCE_LOOP_COUNT * TEST_ENCODE.length()) / diff
+ "kB/sec");
}
/**
* Test vectors for encoding. Taken from the Apache commons project.
*/
public void testKnownEncodings ()
{
assertEquals("test encoding with text",
"VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBk"
+ "b2dzLg==",
Base64Util.encode("The quick brown fox jumped over the lazy dogs."
.getBytes()));
assertEquals("test encoding with text",
"SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0"
+ "IG9mIHRpbWVzLg==",
Base64Util.encode(
"It was the best of times, it was the worst of times."
.getBytes()));
assertEquals("test encoding with URL",
"aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw==",
Base64Util.encode("http://jakarta.apache.org/commmons".getBytes()));
assertEquals("test encoding with all letters",
"QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1"
+ "VnZXd1h4WXlaeg==",
Base64Util.encode(
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
.getBytes()));
assertEquals("test encoding with digits",
"eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0=",
Base64Util.encode("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }".getBytes()));
assertEquals("eHl6enkh",
Base64Util.encode("xyzzy!".getBytes()));
}
/**
* Test vectors for decoding. Taken from the Apache commons project.
*/
public void testKnownDecodings ()
{
assertEquals("test decoding with text",
"The quick brown fox jumped over the lazy dogs.",
StringUtil.asciiToString(Base64Util.decode(
"VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg"
+ "==")));
assertEquals("test decoding with text",
"It was the best of times, it was the worst of times.",
StringUtil.asciiToString(Base64Util.decode(
"SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIH"
+ "RpbWVzLg==")));
assertEquals("test decoding with URL",
"http://jakarta.apache.org/commmons",
StringUtil.asciiToString(Base64Util.decode(
"aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw==")));
assertEquals("test decoding with letters",
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
StringUtil.asciiToString(Base64Util.decode(
"QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1"
+ "h4WXlaeg==")));
assertEquals("test decoding with digits",
"{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }",
StringUtil.asciiToString(Base64Util.decode(
"eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0=")));
assertEquals("test decoding with another test vector",
"xyzzy!",
StringUtil.asciiToString(Base64Util.decode("eHl6enkh")));
}
/**
* Test vectors for encoding. Taken from the Apache commons project.
*/
public void testSingletons ()
{
final String[] testVectors = new String[]{
"AA==", "AQ==", "Ag==",
"Aw==", "BA==", "BQ==", "Bg==", "Bw==", "CA==", "CQ==", "Cg==",
"Cw==", "DA==", "DQ==", "Dg==", "Dw==", "EA==", "EQ==", "Eg==",
"Ew==", "FA==", "FQ==", "Fg==", "Fw==", "GA==", "GQ==", "Gg==",
"Gw==", "HA==", "HQ==", "Hg==", "Hw==", "IA==", "IQ==", "Ig==",
"Iw==", "JA==", "JQ==", "Jg==", "Jw==", "KA==", "KQ==", "Kg==",
"Kw==", "LA==", "LQ==", "Lg==", "Lw==", "MA==", "MQ==", "Mg==",
"Mw==", "NA==", "NQ==", "Ng==", "Nw==", "OA==", "OQ==", "Og==",
"Ow==", "PA==", "PQ==", "Pg==", "Pw==", "QA==", "QQ==", "Qg==",
"Qw==", "RA==", "RQ==", "Rg==", "Rw==", "SA==", "SQ==", "Sg==",
"Sw==", "TA==", "TQ==", "Tg==", "Tw==", "UA==", "UQ==", "Ug==",
"Uw==", "VA==", "VQ==", "Vg==", "Vw==", "WA==", "WQ==", "Wg==",
"Ww==", "XA==", "XQ==", "Xg==", "Xw==", "YA==", "YQ==", "Yg==",
"Yw==", "ZA==", "ZQ==", "Zg==", "Zw==", "aA=="
};
for (int i = 0; i < testVectors.length; i++)
{
assertEquals("single byte decoding test vector[" + i + "]",
testVectors[i], Base64Util.encode(new byte[] {(byte) i}));
}
}
/**
* Test vectors with three bytes that tests the Base64 encoding.
*/
public void testTriplets ()
{
final String[] testVectors = new String[]{
"AAAA", "AAAB", "AAAC", "AAAD",
"AAAE", "AAAF", "AAAG", "AAAH", "AAAI", "AAAJ", "AAAK", "AAAL",
"AAAM", "AAAN", "AAAO", "AAAP", "AAAQ", "AAAR", "AAAS", "AAAT",
"AAAU", "AAAV", "AAAW", "AAAX", "AAAY", "AAAZ", "AAAa", "AAAb",
"AAAc", "AAAd", "AAAe", "AAAf", "AAAg", "AAAh", "AAAi", "AAAj",
"AAAk", "AAAl", "AAAm", "AAAn", "AAAo", "AAAp", "AAAq", "AAAr",
"AAAs", "AAAt", "AAAu", "AAAv", "AAAw", "AAAx", "AAAy", "AAAz",
"AAA0", "AAA1", "AAA2", "AAA3", "AAA4", "AAA5", "AAA6", "AAA7",
"AAA8", "AAA9", "AAA+", "AAA/"
};
for (int i = 0; i < testVectors.length; i++)
{
assertEquals("three byte encoding vector[" + i + "]",
testVectors[i],
Base64Util.encode(new byte[] {(byte) 0, (byte) 0, (byte) i}));
}
}
public void testDecodeWithMalformedData ()
{
decodeWithMalformedDataTest(null);
decodeWithMalformedDataTest("");
decodeWithMalformedDataTest("a");
decodeWithMalformedDataTest("ab");
decodeWithMalformedDataTest("abc");
decodeWithMalformedDataTest("====");
decodeWithMalformedDataTest("3c=r");
decodeWithMalformedDataTest("dGVzd===");
decodeWithMalformedDataTest("3c==");
decodeWithMalformedDataTest("dGVzd!==");
decodeWithMalformedDataTest("3cd$");
decodeWithMalformedDataTest("3c$d");
decodeWithMalformedDataTest("3c$$");
}
private void decodeWithMalformedDataTest (String s)
{
try
{
final byte[] data = Base64Util.decode(s);
fail("Expected ArgumentMalformedException for the malformed "
+ "base64 data : '" + s + "' result is "
+ HexUtil.bytesToHex(data));
}
catch (ArgumentMalformedException x)
{
// expected
}
}
private void checkEncodeDecode (byte[] data)
{
assertTrue("Encode decode should be idempotent (" + data.length + ")",
Arrays.equals(data, Base64Util.decode(Base64Util.encode(data))));
}
}