Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
15 views8 pages

Base 64

The document provides a Java implementation of Base64 encoding and decoding. It includes classes for encoding and decoding, with support for various flags such as padding, wrapping, and URL safety. The main functionalities include methods to decode strings and byte arrays, as well as to encode byte arrays into Base64 format.

Uploaded by

Marco Otto
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views8 pages

Base 64

The document provides a Java implementation of Base64 encoding and decoding. It includes classes for encoding and decoding, with support for various flags such as padding, wrapping, and URL safety. The main functionalities include methods to decode strings and byte arrays, as well as to encode byte arrays into Base64 format.

Uploaded by

Marco Otto
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8

import java.io.

UnsupportedEncodingException;

public class Base64 {


public static final int DEFAULT = 0;

public static final int NO_PADDING = 1;

public static final int NO_WRAP = 2;

public static final int CRLF = 4;

public static final int URL_SAFE = 8;

public static final int NO_CLOSE = 16;

static abstract class Coder {


public byte[] output;

public int op;

public abstract boolean process(byte[] param1ArrayOfbyte, int param1Int1, int


param1Int2, boolean param1Boolean);

public abstract int maxOutputSize(int param1Int);


}

public static byte[] decode(String str, int flags) {


return decode(str.getBytes(), flags);
}

public static byte[] decode(byte[] input, int flags) {


return decode(input, 0, input.length, flags);
}

public static byte[] decode(byte[] input, int offset, int len, int flags) {
Decoder decoder = new Decoder(flags, new byte[len * 3 / 4]);
if (!decoder.process(input, offset, len, true))
throw new IllegalArgumentException("bad base-64");
if (decoder.op == decoder.output.length)
return decoder.output;
byte[] temp = new byte[decoder.op];
System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
return temp;
}

static class Decoder extends Coder {


private static final int[] DECODE = new int[] {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -2, -1, -1, -1, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1 };

private static final int[] DECODE_WEBSAFE = new int[] {


-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 62, -1, -1, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -2, -1, -1, -1, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, -1, -1, -1, -1, 63, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1 };

private static final int SKIP = -1;

private static final int EQUALS = -2;

private int state;

private int value;

private final int[] alphabet;

public Decoder(int flags, byte[] output) {


this.output = output;
this.alphabet = ((flags & 0x8) == 0) ? DECODE : DECODE_WEBSAFE;
this.state = 0;
this.value = 0;
}

public int maxOutputSize(int len) {


return len * 3 / 4 + 10;
}

public boolean process(byte[] input, int offset, int len, boolean finish) {
if (this.state == 6)
return false;
int p = offset;
len += offset;
int state = this.state;
int value = this.value;
int op = 0;
byte[] output = this.output;
int[] alphabet = this.alphabet;
while (p < len) {
if (state == 0) {
while (p + 4 <= len && (value = alphabet[input[p] & 0xFF] << 18 |
alphabet[input[p + 1] & 0xFF] << 12 | alphabet[input[p + 2] & 0xFF] << 6 |
alphabet[input[p + 3] & 0xFF]) >= 0) {
output[op + 2] = (byte)value;
output[op + 1] = (byte)(value >> 8);
output[op] = (byte)(value >> 16);
op += 3;
p += 4;
}
if (p >= len)
break;
}
int d = alphabet[input[p++] & 0xFF];
switch (state) {
case 0:
if (d >= 0) {
value = d;
state++;
continue;
}
if (d != -1) {
this.state = 6;
return false;
}
case 1:
if (d >= 0) {
value = value << 6 | d;
state++;
continue;
}
if (d != -1) {
this.state = 6;
return false;
}
case 2:
if (d >= 0) {
value = value << 6 | d;
state++;
continue;
}
if (d == -2) {
output[op++] = (byte)(value >> 4);
state = 4;
continue;
}
if (d != -1) {
this.state = 6;
return false;
}
case 3:
if (d >= 0) {
value = value << 6 | d;
output[op + 2] = (byte)value;
output[op + 1] = (byte)(value >> 8);
output[op] = (byte)(value >> 16);
op += 3;
state = 0;
continue;
}
if (d == -2) {
output[op + 1] = (byte)(value >> 2);
output[op] = (byte)(value >> 10);
op += 2;
state = 5;
continue;
}
if (d != -1) {
this.state = 6;
return false;
}
case 4:
if (d == -2) {
state++;
continue;
}
if (d != -1) {
this.state = 6;
return false;
}
case 5:
if (d != -1) {
this.state = 6;
return false;
}
}
}
if (!finish) {
this.state = state;
this.value = value;
this.op = op;
return true;
}
switch (state) {
case 1:
this.state = 6;
return false;
case 2:
output[op++] = (byte)(value >> 4);
break;
case 3:
output[op++] = (byte)(value >> 10);
output[op++] = (byte)(value >> 2);
break;
case 4:
this.state = 6;
return false;
}
this.state = state;
this.op = op;
return true;
}
}

public static String encodeToString(byte[] input, int flags) {


try {
return new String(encode(input, flags), "US-ASCII");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}

public static String encodeToString(byte[] input, int offset, int len, int flags)
{
try {
return new String(encode(input, offset, len, flags), "US-ASCII");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}

public static byte[] encode(byte[] input, int flags) {


return encode(input, 0, input.length, flags);
}

public static byte[] encode(byte[] input, int offset, int len, int flags) {
Encoder encoder = new Encoder(flags, null);
int output_len = len / 3 * 4;
if (encoder.do_padding) {
if (len % 3 > 0)
output_len += 4;
} else {
switch (len % 3) {
case 1:
output_len += 2;
break;
case 2:
output_len += 3;
break;
}
}
if (encoder.do_newline && len > 0)
output_len += ((len - 1) / 57 + 1) * (
encoder.do_cr ? 2 : 1);
encoder.output = new byte[output_len];
encoder.process(input, offset, len, true);
assert encoder.op == output_len;
return encoder.output;
}
static class Encoder extends Coder {
public static final int LINE_GROUPS = 19;

private static final byte[] ENCODE = new byte[] {


65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 43, 47 };

private static final byte[] ENCODE_WEBSAFE = new byte[] {


65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 45, 95 };

private final byte[] tail;

int tailLen;

private int count;

public final boolean do_padding;

public final boolean do_newline;

public final boolean do_cr;

private final byte[] alphabet;

public Encoder(int flags, byte[] output) {


this.output = output;
this.do_padding = ((flags & 0x1) == 0);
this.do_newline = ((flags & 0x2) == 0);
this.do_cr = ((flags & 0x4) != 0);
this.alphabet = ((flags & 0x8) == 0) ? ENCODE : ENCODE_WEBSAFE;
this.tail = new byte[2];
this.tailLen = 0;
this.count = this.do_newline ? 19 : -1;
}

public int maxOutputSize(int len) {


return len * 8 / 5 + 10;
}

public boolean process(byte[] input, int offset, int len, boolean finish) {
byte[] alphabet = this.alphabet;
byte[] output = this.output;
int op = 0;
int count = this.count;
int p = offset;
len += offset;
int v = -1;
switch (this.tailLen) {
case 1:
if (p + 2 <= len) {
v = (this.tail[0] & 0xFF) << 16 | (input[p++] & 0xFF) << 8 | input[p++]
& 0xFF;
this.tailLen = 0;
}
break;
case 2:
if (p + 1 <= len) {
v = (this.tail[0] & 0xFF) << 16 | (this.tail[1] & 0xFF) << 8 | input[p+
+] & 0xFF;
this.tailLen = 0;
}
break;
}
if (v != -1) {
output[op++] = alphabet[v >> 18 & 0x3F];
output[op++] = alphabet[v >> 12 & 0x3F];
output[op++] = alphabet[v >> 6 & 0x3F];
output[op++] = alphabet[v & 0x3F];
if (--count == 0) {
if (this.do_cr)
output[op++] = 13;
output[op++] = 10;
count = 19;
}
}
while (p + 3 <= len) {
v = (input[p] & 0xFF) << 16 | (input[p + 1] & 0xFF) << 8 | input[p + 2] &
0xFF;
output[op] = alphabet[v >> 18 & 0x3F];
output[op + 1] = alphabet[v >> 12 & 0x3F];
output[op + 2] = alphabet[v >> 6 & 0x3F];
output[op + 3] = alphabet[v & 0x3F];
p += 3;
op += 4;
if (--count == 0) {
if (this.do_cr)
output[op++] = 13;
output[op++] = 10;
count = 19;
}
}
if (finish) {
if (p - this.tailLen == len - 1) {
int t = 0;
v = (((this.tailLen > 0) ? this.tail[t++] : input[p++]) & 0xFF) << 4;
this.tailLen -= t;
output[op++] = alphabet[v >> 6 & 0x3F];
output[op++] = alphabet[v & 0x3F];
if (this.do_padding) {
output[op++] = 61;
output[op++] = 61;
}
if (this.do_newline) {
if (this.do_cr)
output[op++] = 13;
output[op++] = 10;
}
} else if (p - this.tailLen == len - 2) {
int t = 0;
v = (((this.tailLen > 1) ? this.tail[t++] : input[p++]) & 0xFF) << 10 |
(((this.tailLen > 0) ? this.tail[t++] : input[p++]) & 0xFF) << 2;
this.tailLen -= t;
output[op++] = alphabet[v >> 12 & 0x3F];
output[op++] = alphabet[v >> 6 & 0x3F];
output[op++] = alphabet[v & 0x3F];
if (this.do_padding)
output[op++] = 61;
if (this.do_newline) {
if (this.do_cr)
output[op++] = 13;
output[op++] = 10;
}
} else if (this.do_newline && op > 0 && count != 19) {
if (this.do_cr)
output[op++] = 13;
output[op++] = 10;
}
assert this.tailLen == 0;
assert p == len;
} else if (p == len - 1) {
this.tail[this.tailLen++] = input[p];
} else if (p == len - 2) {
this.tail[this.tailLen++] = input[p];
this.tail[this.tailLen++] = input[p + 1];
}
this.op = op;
this.count = count;
return true;
}
}
}

You might also like