Added Base64Encoder

This commit is contained in:
Ziver Koc 2015-11-17 18:59:50 +01:00
parent 67e4d54fde
commit 034166b413
7 changed files with 219 additions and 57 deletions

16
src/zutil/converters/Converter.java Normal file → Executable file
View file

@ -170,22 +170,6 @@ public class Converter {
return object;
}
/**
* Checks if the given interface is implemented in the object
*
* @param object the object to look for the interface
* @param interf the interface to look for
* @return true if the interface is implemented else false
*/
public static boolean isInstanceOf(Object object, Class<?> interf){
Class<?>[] objectInterf = object.getClass().getInterfaces();
for(int i=0; i<objectInterf.length ;i++){
if(objectInterf[i] == interf){
return true;
}
}
return false;
}
/** array needed for byteToHex */
private static char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

14
src/zutil/parser/BBCodeParser.java Normal file → Executable file
View file

@ -59,9 +59,9 @@ public class BBCodeParser {
/**
* Registers a new BBCode to the parser. Only one type of BBCode allowed.
*
* @param bbcode is the BBCode e.g. "b" or "url"
* @param html is the corresponding HTML e.g. "<a href='%1'>%2</a>"
* where the %x corresponds to BBCode like this: [url=%1]%2[/url]
* @param bbcode is the BBCode e.g. "b" or "url"
* @param html is the corresponding HTML e.g. "<a href='%1'>%2</a>"
* where the %x corresponds to BBCode like this: [url=%1]%2[/url]
*/
public void addBBCode(String bbcode, String html){
bbcodes.put(bbcode, html);
@ -70,7 +70,7 @@ public class BBCodeParser {
/**
* Removes a BBCode definition from the parser
*
* @param bbcode is the bbcode to remove
* @param bbcode is the bbcode to remove
*/
public void removeBBCode(String bbcode){
bbcodes.remove(bbcode);
@ -79,7 +79,7 @@ public class BBCodeParser {
/**
* Parses the text with BBCode and converts it to HTML
*
* @param text is a String with BBCode
* @param text is a String with BBCode
* @return a String where all BBCode has been replaced by HTML
*/
public String read(String text){
@ -149,7 +149,7 @@ public class BBCodeParser {
/**
* Parses a parameter from a BBCode block: [url=param]
*
* @param text is the text to parse from
* @param text is the text to parse from
* @return only the parameter string
*/
private String parseParam(MutableInt index, StringBuilder text){
@ -168,7 +168,7 @@ public class BBCodeParser {
/**
* Parses the value in the BBCodes e.g. [url]value[/url]
*
* @param text is the text to parse the value from
* @param text is the text to parse the value from
*/
private String parseValue(MutableInt index, StringBuilder text, String bbcode){
StringBuilder value = new StringBuilder();

14
src/zutil/parser/BEncodedParser.java Normal file → Executable file
View file

@ -37,7 +37,7 @@ public class BEncodedParser {
/**
* Returns the representation of the data in the BEncoded string
*
* @param data The data to be decoded
* @param data is the data to be decoded
* @return
*/
public static DataNode read(String data){
@ -47,8 +47,8 @@ public class BEncodedParser {
/**
* Returns the representation of the data in the BEncoded string
*
* @param data The data to be decoded
* @param index The index in data to start from
* @param data is the data to be decoded
* @param index is the index in data to start from
* @return
*/
private static DataNode decode_BEncoded(MutableInt index, StringBuilder data){
@ -62,11 +62,9 @@ public class BEncodedParser {
* i-3272002e.
*/
case 'i':
//System.out.println("Found Integer at "+index);
index.i++;
tmp = data.substring(index.i, data.indexOf("e"));
index.i += tmp.length() + 1;
//System.out.println(tmp);
return new DataNode( new Long(tmp));
/**
* Lists are prefixed with a l and terminated by an e. The list
@ -76,7 +74,6 @@ public class BEncodedParser {
* would bEncode to li1e7:Mondunai3el3:Sub4:Listee
*/
case 'l':
//System.out.println("Found List at "+index);
index.i++;
DataNode list = new DataNode( DataType.List );
c = data.charAt(index.i);
@ -85,7 +82,6 @@ public class BEncodedParser {
c = data.charAt(index.i);
}
index.i++;
//MultiPrintStream.out.dump(list);
if(list.size() == 1) return list.get(0);
else return list;
/**
@ -95,7 +91,6 @@ public class BEncodedParser {
* would bEncode to d3:key5:value7:Monduna3:com3:bit:8:Torrents6:numberi7ee
*/
case 'd':
//System.out.println("Found Dictionary at "+index);
index.i++;
DataNode map = new DataNode( DataType.Map );
c = data.charAt(index.i);
@ -105,7 +100,6 @@ public class BEncodedParser {
c = data.charAt(index.i);
}
index.i++;
//MultiPrintStream.out.dump(map);
return map;
/**
* Strings are prefixed with their length followed by a colon.
@ -113,13 +107,11 @@ public class BEncodedParser {
* would bEncode to 11:BitTorrents.
*/
default:
//System.out.println("Found String at "+index);
tmp = data.substring(index.i, data.indexOf(":"));
int length = Integer.parseInt(tmp);
index.i += tmp.length() + 1;
String ret = data.substring(index.i, length);
index.i += length;
//System.out.println(data.substring(i, i+length));
return new DataNode( ret );
}
}

22
src/zutil/parser/Base64Decoder.java Normal file → Executable file
View file

@ -52,23 +52,23 @@ public class Base64Decoder {
public static String decode( String data ){
Base64Decoder base64 = new Base64Decoder();
base64.write( data );
base64.read( data );
return base64.toString();
}
public static String decodeToHex( String data ){
Base64Decoder base64 = new Base64Decoder();
base64.write( data );
base64.read( data );
return Converter.toHexString( base64.getByte() );
}
public static byte[] decodeToByte( String data ){
Base64Decoder base64 = new Base64Decoder();
base64.write( data );
base64.read( data );
return base64.getByte();
}
public void write( String data ){
public void read( String data ){
byte[] buffer = new byte[ (data.length()*6/8) + 1 ];
int buffi = 0;
if( rest != 0 )
@ -120,19 +120,9 @@ public class Base64Decoder {
rest = 0;
rest_data = 0;
}
public static String addPadding( String data ){
int padding = 4 - (data.length() % 4);
switch( padding ){
case 0: return data;
case 1: return data + "=";
case 2: return data + "==";
case 3: return data + "===";
}
return null;
}
private byte getByte( char c ){
private static byte getByte( char c ){
switch(c){
case 'A': return (byte)( 0 & 0xff);
case 'B': return (byte)( 1 & 0xff);

View file

@ -0,0 +1,162 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package zutil.parser;
public class Base64Encoder {
public static String encode( byte[] data ){
Base64Encoder base64 = new Base64Encoder();
return base64.write( data );
}
public static String encode( String data ){
Base64Encoder base64 = new Base64Encoder();
return base64.write( data.getBytes() );
}
private static String write( byte[] data ){
char[] buffer = new char[getBufferLength(data.length)];
int buffIndex = 0;
int rest = 0; // how much rest we have
for( int i=0; i<data.length; i++){
byte b = 0;
switch(rest){
case 0:
b = (byte)((data[i] >> 2) & 0b0011_1111);
break;
case 2:
b = (byte) ((data[i-1] << 4) & 0b0011_0000);
b |= (byte) ((data[i] >> 4) & 0b0000_1111);
break;
case 4:
b = (byte) ((data[i-1] << 2) & 0b0011_1100);
b |= (byte) ((data[i] >> 6) & 0b0000_0011);
break;
case 6:
--i; // Go back one element
b = (byte) (data[i] & 0b0011_1111);
break;
}
rest = (rest + 2) % 8;
buffer[buffIndex++] = getChar(b);
}
// Any rest left?
if(rest == 2)
buffer[buffIndex++] = getChar((byte) ((data[data.length-1] << 4) & 0b0011_0000));
else if(rest == 4)
buffer[buffIndex++] = getChar((byte) ((data[data.length-1] << 2) & 0b0011_1100));
else if(rest == 6)
buffer[buffIndex++] = getChar((byte) (data[data.length-1] & 0b0011_1111));
// Add padding
for(; buffIndex<buffer.length; ++buffIndex)
buffer[buffIndex] = '=';
return new String(buffer);
}
private static int getBufferLength(int length) {
int buffLength = (int) Math.ceil(length*8/6.0);
// Padding
if(buffLength%4 != 0)
buffLength += 4 - buffLength%4;
return buffLength;
}
private static char getChar( byte b ){
switch(b){
case (byte)( 0 & 0xff): return 'A';
case (byte)( 1 & 0xff): return 'B';
case (byte)( 2 & 0xff): return 'C';
case (byte)( 3 & 0xff): return 'D';
case (byte)( 4 & 0xff): return 'E';
case (byte)( 5 & 0xff): return 'F';
case (byte)( 6 & 0xff): return 'G';
case (byte)( 7 & 0xff): return 'H';
case (byte)( 8 & 0xff): return 'I';
case (byte)( 9 & 0xff): return 'J';
case (byte)(10 & 0xff): return 'K';
case (byte)(11 & 0xff): return 'L';
case (byte)(12 & 0xff): return 'M';
case (byte)(13 & 0xff): return 'N';
case (byte)(14 & 0xff): return 'O';
case (byte)(15 & 0xff): return 'P';
case (byte)(16 & 0xff): return 'Q';
case (byte)(17 & 0xff): return 'R';
case (byte)(18 & 0xff): return 'S';
case (byte)(19 & 0xff): return 'T';
case (byte)(20 & 0xff): return 'U';
case (byte)(21 & 0xff): return 'V';
case (byte)(22 & 0xff): return 'W';
case (byte)(23 & 0xff): return 'X';
case (byte)(24 & 0xff): return 'Y';
case (byte)(25 & 0xff): return 'Z';
case (byte)(26 & 0xff): return 'a';
case (byte)(27 & 0xff): return 'b';
case (byte)(28 & 0xff): return 'c';
case (byte)(29 & 0xff): return 'd';
case (byte)(30 & 0xff): return 'e';
case (byte)(31 & 0xff): return 'f';
case (byte)(32 & 0xff): return 'g';
case (byte)(33 & 0xff): return 'h';
case (byte)(34 & 0xff): return 'i';
case (byte)(35 & 0xff): return 'j';
case (byte)(36 & 0xff): return 'k';
case (byte)(37 & 0xff): return 'l';
case (byte)(38 & 0xff): return 'm';
case (byte)(39 & 0xff): return 'n';
case (byte)(40 & 0xff): return 'o';
case (byte)(41 & 0xff): return 'p';
case (byte)(42 & 0xff): return 'q';
case (byte)(43 & 0xff): return 'r';
case (byte)(44 & 0xff): return 's';
case (byte)(45 & 0xff): return 't';
case (byte)(46 & 0xff): return 'u';
case (byte)(47 & 0xff): return 'v';
case (byte)(48 & 0xff): return 'w';
case (byte)(49 & 0xff): return 'w';
case (byte)(50 & 0xff): return 'y';
case (byte)(51 & 0xff): return 'z';
case (byte)(52 & 0xff): return '0';
case (byte)(53 & 0xff): return '1';
case (byte)(54 & 0xff): return '2';
case (byte)(55 & 0xff): return '3';
case (byte)(56 & 0xff): return '4';
case (byte)(57 & 0xff): return '5';
case (byte)(58 & 0xff): return '6';
case (byte)(59 & 0xff): return '7';
case (byte)(60 & 0xff): return '8';
case (byte)(61 & 0xff): return '9';
case (byte)(62 & 0xff): return '+';
case (byte)(63 & 0xff): return '/';
}
return 0;
}
}

View file

@ -26,6 +26,7 @@ package zutil.parser.json;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import zutil.ClassUtil;
import zutil.parser.Base64Encoder;
import zutil.parser.DataNode;
import zutil.parser.DataNode.DataType;
import static zutil.parser.json.JSONObjectInputStream.*;
@ -86,9 +87,17 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
}
// Add an array
else if(objClass.isArray()){
root = new DataNode(DataNode.DataType.List);
for(int i=0; i< Array.getLength(obj) ;i++){
root.add(getDataNode(Array.get(obj, i)));
// Special case for byte arrays
if(objClass.getComponentType() == byte[].class) {
root = new DataNode(DataType.String);
root.set(Base64Encoder.encode((byte[])obj));
}
// Other arrays
else {
root = new DataNode(DataType.List);
for (int i = 0; i < Array.getLength(obj); i++) {
root.add(getDataNode(Array.get(obj, i)));
}
}
}
// List

33
test/zutil/test/Base64Test.java Normal file → Executable file
View file

@ -25,27 +25,52 @@ package zutil.test;
import org.junit.Test;
import zutil.parser.Base64Decoder;
import zutil.parser.Base64Encoder;
import java.util.Base64;
import static org.junit.Assert.assertEquals;
public class Base64Test {
@Test
public void testHexToByte() {
public void decode() {
assertEquals( "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.",
Base64Decoder.decode("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=")
);
Base64Decoder decoder = new Base64Decoder();
decoder.clear();
decoder.write("YW55IGNhcm5hbCBwbGVhc3VyZQ==");
decoder.read("YW55IGNhcm5hbCBwbGVhc3VyZQ==");
assertEquals( "any carnal pleasure", decoder.toString() );
decoder.clear();
decoder.write("bGVhc3VyZS4=");
decoder.read("bGVhc3VyZS4=");
assertEquals( "leasure.", decoder.toString() );
decoder.clear();
decoder.write("YW55IGNhcm5hbCBwbGVhc3Vy");
decoder.read("YW55IGNhcm5hbCBwbGVhc3Vy");
assertEquals( "any carnal pleasur", decoder.toString() );
decoder.clear();
}
@Test
public void encode() {
/*assertEquals("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=" ,
Base64Encoder.encode("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.")
);*/
assertEquals("YW55IGNhcm5hbCBwbGVhc3VyZQ==", Base64Encoder.encode("any carnal pleasure"));
assertEquals("bGVhc3VyZS4=", Base64Encoder.encode("leasure."));
assertEquals("YW55IGNhcm5hbCBwbGVhc3Vy", Base64Encoder.encode("any carnal pleasur"));
}
@Test
public void encodeJavaUtil() {
/*assertEquals("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=" ,
Base64.getEncoder().encodeToString("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.".getBytes())
);*/
assertEquals("YW55IGNhcm5hbCBwbGVhc3VyZQ==", Base64.getEncoder().encodeToString("any carnal pleasure".getBytes()));
assertEquals("bGVhc3VyZS4=", Base64.getEncoder().encodeToString("leasure.".getBytes()));
assertEquals("YW55IGNhcm5hbCBwbGVhc3Vy", Base64.getEncoder().encodeToString("any carnal pleasur".getBytes()));
}
}