Wednesday, August 22, 2007

Base64 With Java

The following source code is implementation of Base64 Algorithm using JAVA :


import java.util.Scanner;
import java.lang.*;
import java.io.*;
import java.nio.ByteBuffer;

public class Base64
{
//public static String B64Tablea = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
private static byte[] Encode(byte source[])
{
//String hrmm = "";
//for(int i = 0; i < source.length; i++)
// hrmm += B64Tablea.charAt((source[i] >> 2) & 0x3f);
//System.out.println("Test: " + hrmm);

byte binaryStream[] = BinaryStream(source, true); // Convert to binary stream
int binLen = binaryStream.length;
int padding = binLen % 3; // Calculate padding

byte encodeBlock[] = new byte[6]; // Encode blocks of 6 chars
ByteBuffer encodeData = ByteBuffer.allocate(binLen / 6 + padding + 1);
System.out.println("Converting data blocks to Base64 chars...");
for(int i = 0; i < binLen; i += 6)
{
for(int j = 0; j < 6; j++) // Fill block with binary data
{
if(i + j == binLen) break;
encodeBlock[j] = binaryStream[j + i];
}
encodeData.put((byte) Base64Table(encodeBlock)); // Add encoded data

for(int j = 0; j < 6; j++)
encodeBlock[j] = '0';
}
for(int i = 0; i < padding; i++) // Pad data
encodeData.put((byte)'=');
System.out.println("Encoding complete.");
return encodeData.array();
}

private static char Base64Table(byte encodeBlock[])
{
int bits[] = {32, 16, 8, 4, 2, 1}; // Bit values
String B64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int totalBits = 0;

for(int i = 0; i < 6; i++) // Calculate total bits
if(encodeBlock[i] == '1')
totalBits += bits[i];

return B64Table.charAt(totalBits); // Return char found in calculated index
}

private static byte[] BinaryStream(byte source[], Boolean isEncoding)
{
System.out.println("Streaming binary output...");
int srcLen = source.length;

byte asc = 0; int pad = 0; int val = 0; int encodeVal = 0;

if(isEncoding == true)
encodeVal = 8;
else
encodeVal = 6;

ByteBuffer binaryStream = ByteBuffer.allocate(srcLen * encodeVal);
int b[] = {1, 2, 4, 8, 16, 32, 64, 128, 255};
for(int i = 0; i < srcLen; i++)
{
//StringBuffer buffer = new StringBuffer(); // Stores binary values
asc = (byte) source[i]; // Retrieve ascii value

//pad = encodeVal - 8;
//for(int j = 0; j < pad; j++) // Fill the buffer with padding
// binaryStream.put((byte)'0');

for(int bit = 1; bit < encodeVal + 1; bit++) //New method to retrieve binary
binaryStream.put((asc & b[encodeVal - bit]) > 0 == true ? (byte) '1' : (byte) '0');


/*
while(true) // Compute and store binary values
{
val = asc % 2;

buffer.append( val == 0 ? '0' : '1');

asc >>= 1;

if(asc == 0)
break;

}


pad = encodeVal - buffer.length(); // Calculate padding

for(int j = 0; j < pad; j++) // Fill the buffer with padding
binaryStream.put((byte)'0');

binaryStream.put(buffer.reverse().toString().getBytes());
*/


}
System.out.println("Streaming binary complete.");
return binaryStream.array();

}

private static byte[] Decode(byte source[])
{
System.out.println("Converting Base64 Data to byte array...");
byte decodeTable[] = Base64Table2(source);
System.out.println("Conversion completed.");
byte binaryStream[] = BinaryStream(decodeTable, false);
System.out.println("Decoding binary stream to file data...");
byte decodeStream[] = DecodeStream(binaryStream);
System.out.println("File successfully decoded.");
return decodeStream;
}

private static byte[] Base64Table2(byte source[])
{
int srcLen = source.length;
ByteBuffer decodeTable = ByteBuffer.allocate(srcLen);
int bits[] = {32, 16, 8, 4, 2, 1};
String B64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int totalBits = 0;

for(int i = 0; i < srcLen; i++)
for(int j = 0; j < 64; j++)
if((char) source[i] == B64Table.charAt(j))
{
decodeTable.put((byte) j);
break;
}
return decodeTable.array();
}

private static byte[] DecodeStream(byte binaryStream[])
{
int srcLen = binaryStream.length;

int bits[] = {128, 64, 32, 16, 8, 4, 2, 1};
int totalBits = 0;

ByteBuffer decodeStream = ByteBuffer.allocate(srcLen / 8);

for(int i = 0; i < srcLen; i += 8)
{
totalBits = 0;
for(int j = 0; j < 8; j++)
{
if(i + j == srcLen) break;
if(binaryStream[i + j] == (byte)'1')
totalBits += bits[j];
}
decodeStream.put((byte) totalBits);
}
return decodeStream.array();
}

private static byte[] readFile(String fileName)
{
FileInputStream fis = null;
File input_file = new File(fileName);
int bytesRead = 0;
int fileLength = (int) input_file.length();
byte buffer[] = new byte[fileLength];

try{

fis = new FileInputStream(input_file);
}
catch(IOException e){
System.out.println("Could not read file: " + fileName);
}


try{
bytesRead = fis.read(buffer);
}
catch(IOException e){
System.out.println("Could not read file: " + fileName);
}

return buffer;
}

private static void writeFile(byte data[], String fileName)
{
FileOutputStream fos = null;
File output_file = new File(fileName);

try{
fos = new FileOutputStream(output_file);
}
catch(IOException e){
System.out.println("Could not create file: " + fileName);
}

try{
fos.write(data, 0, data.length);
}
catch(IOException e){
System.out.println("Could not write to file: " + fileName);
}

}
public static void main( String args[] )
{
/*
Arg # Argument Description
-----------------------------------------------------
args[0] -encode Encode Base64
-decode Decode Base64

args[1] -f Encoding/Decoding file
-s Encoding/Decoding string

args[2] -"" Path of source data
-"" Source Data string

args[3] -"" Define output location.
If undefined, outputs to
path of file ".base64"
unless -s argument is used
then it will be directly
outputted to console.
*/

if(args.length < 3)
DisplayHelp(10);
else
{
if(args[0].compareToIgnoreCase("-encode") == 0)
{
if(args[1].compareToIgnoreCase("-f") == 0)
{
byte encode_data[] = Encode(readFile(args[2]));
if(args.length != 4)
writeFile(encode_data, args[2] + ".base64");
else
writeFile(encode_data, args[3]);
}
else if(args[1].compareToIgnoreCase("-s") == 0)
{
byte encode_data[] = Encode(args[2].getBytes());
if(args.length != 4)
System.out.println("\n\nString Output: \n" + new String(encode_data) + "\n");
else
writeFile(encode_data, args[3]);
}
else
DisplayHelp(1);
}
else if(args[0].compareToIgnoreCase("-decode") == 0)
{
if(args[1].compareToIgnoreCase("-f") == 0)
{
byte decode_data[] = Decode(readFile(args[2]));
if(args.length != 4)
writeFile(decode_data, args[2] + ".base64");
else
writeFile(decode_data, args[3]);
}
else if(args[1].compareToIgnoreCase("-s") == 0)
{
byte decode_data[] = Decode(args[2].getBytes());
if(args.length != 4)
System.out.println("\n\nString Output: \n" + new String(decode_data) + "\n");
else
writeFile(decode_data, args[3]);
}
}
else
DisplayHelp(0);
}
/*
byte encoded_data[] = Encode(readFile("H:/zipper.zip"));
writeFile(encoded_data, "H:/zipper2.base64");
System.out.println();
System.out.print(new String(encoded_data));
System.out.println();
*/
}

private static void DisplayHelp(int argNum){
if(argNum != 10)
System.out.println("Arg[" + argNum + "] is not valid. Please read the table below: \n");
else
System.out.println("Not enough arguments have been passed. Read the table below: \n");

System.out.println("Arg #\tArgument\t\t\tDescription");
System.out.println("-----------------------------------------------------");
System.out.println("arg[0]\t-encode\t\t\t\tEncode Base64");
System.out.println("\t-decode\t\t\t\tDecode Base64\n");
System.out.println("arg[1]\t-f\t\t\t\tEncoding/Decoding file");
System.out.println("\t-s\t\t\t\tEncoding/Decoding string\n");
System.out.println("arg[2]\t (use quotes)\tPath of source data");
System.out.println("\t (use quotes)\tSource Data string\n");
System.out.println("arg[3]\t (use quotes)\tDefine output location. If");
System.out.println("\t\t\t\t\tundefined, outputs to");
System.out.println("\t\t\t\t\tpath of file *.base64");
System.out.println("\t\t\t\t\tunless -s argument is used");
System.out.println("\t\t\t\t\tthen it will directly");
System.out.println("\t\t\t\t\toutputted to console.\n");
System.out.println("Example of use (Encode File):\njava Base64 -encode -f \"C:/file.exe\" \"C:/encoded/file.base64\" ");
}
}
The Above source code is right to copy for anything purpose implementation,
That Source Code is created By : Didik Rawandi

No comments: