package com.opentravelsoft.util;
import java.io.UnsupportedEncodingException;
public class B64Code
{
public B64Code()
{
}
public static String encode(String s)
{
try
{
return encode(s, null);
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return null;
}
public static String encode(String s, String charEncoding)
throws UnsupportedEncodingException
{
byte bytes[];
if (charEncoding == null)
bytes = s.getBytes("ISO_8859_1");
else
bytes = s.getBytes(charEncoding);
return new String(encode(bytes));
}
public static char[] encode(byte b[])
{
if (b == null)
return null;
int bLen = b.length;
char r[] = new char[((bLen + 2) / 3) * 4];
int ri = 0;
int bi = 0;
for (int stop = (bLen / 3) * 3; bi < stop;)
{
byte b0 = b[bi++];
byte b1 = b[bi++];
byte b2 = b[bi++];
r[ri++] = nibble2code[b0 >>> 2 & 0x3f];
r[ri++] = nibble2code[b0 << 4 & 0x3f | b1 >>> 4 & 0xf];
r[ri++] = nibble2code[b1 << 2 & 0x3f | b2 >>> 6 & 3];
r[ri++] = nibble2code[b2 & 0x3f];
}
if (bLen != bi)
switch (bLen % 3)
{
case 2: // '\002'
{
byte b0 = b[bi++];
byte b1 = b[bi++];
r[ri++] = nibble2code[b0 >>> 2 & 0x3f];
r[ri++] = nibble2code[b0 << 4 & 0x3f | b1 >>> 4 & 0xf];
r[ri++] = nibble2code[b1 << 2 & 0x3f];
r[ri++] = '=';
break;
}
case 1: // '\001'
{
byte b0 = b[bi++];
r[ri++] = nibble2code[b0 >>> 2 & 0x3f];
r[ri++] = nibble2code[b0 << 4 & 0x3f];
r[ri++] = '=';
r[ri++] = '=';
break;
}
}
return r;
}
public static String decode(String s)
{
try
{
return decode(s, "ISO_8859_1");
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return null;
}
public static String decode(String s, String charEncoding)
throws UnsupportedEncodingException
{
byte decoded[] = decode(s.toCharArray());
if (charEncoding == null)
return new String(decoded);
else
return new String(decoded, charEncoding);
}
public static byte[] decode(char b[])
{
if (b == null)
return null;
int bLen = b.length;
if (bLen % 4 != 0)
throw new IllegalArgumentException("Input block size is not 4");
int li;
for (li = bLen - 1; li >= 0 && b[li] == '='; li--)
;
if (li < 0)
return new byte[0];
int rLen = ((li + 1) * 3) / 4;
byte r[] = new byte[rLen];
int ri = 0;
int bi = 0;
int stop = (rLen / 3) * 3;
try
{
while (ri < stop)
{
byte b0 = code2nibble[b[bi++]];
byte b1 = code2nibble[b[bi++]];
byte b2 = code2nibble[b[bi++]];
byte b3 = code2nibble[b[bi++]];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException("Not B64 encoded");
r[ri++] = (byte) (b0 << 2 | b1 >>> 4);
r[ri++] = (byte) (b1 << 4 | b2 >>> 2);
r[ri++] = (byte) (b2 << 6 | b3);
}
if (rLen != ri)
switch (rLen % 3)
{
default:
break;
case 2: // '\002'
{
byte b0 = code2nibble[b[bi++]];
byte b1 = code2nibble[b[bi++]];
byte b2 = code2nibble[b[bi++]];
if (b0 < 0 || b1 < 0 || b2 < 0)
throw new IllegalArgumentException("Not B64 encoded");
r[ri++] = (byte) (b0 << 2 | b1 >>> 4);
r[ri++] = (byte) (b1 << 4 | b2 >>> 2);
break;
}
case 1: // '\001'
{
byte b0 = code2nibble[b[bi++]];
byte b1 = code2nibble[b[bi++]];
if (b0 < 0 || b1 < 0)
throw new IllegalArgumentException("Not B64 encoded");
r[ri++] = (byte) (b0 << 2 | b1 >>> 4);
break;
}
}
} catch (IndexOutOfBoundsException e)
{
throw new IllegalArgumentException("char " + bi
+ " was not B64 encoded");
}
return r;
}
static final char pad = 61;
static final char nibble2code[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/' };
static byte code2nibble[];
static
{
code2nibble = null;
code2nibble = new byte[256];
for (int i = 0; i < 256; i++)
code2nibble[i] = -1;
for (byte b = 0; b < 64; b++)
code2nibble[(byte) nibble2code[b]] = b;
code2nibble[61] = 0;
}
}