Base64.java revision 48ded2421114c4c87ef3f8005c9f793a5d077cbd
1/*
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
3 * Please refer to the LICENSE.txt for licensing details.
4 */
5package ch.ethz.ssh2.crypto;
6
7import java.io.CharArrayWriter;
8import java.io.IOException;
9
10/**
11 * Basic Base64 Support.
12 *
13 * @author Christian Plattner
14 * @version 2.50, 03/15/10
15 */
16public class Base64
17{
18	static final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
19
20	public static char[] encode(byte[] content)
21	{
22		CharArrayWriter cw = new CharArrayWriter((4 * content.length) / 3);
23
24		int idx = 0;
25
26		int x = 0;
27
28		for (int i = 0; i < content.length; i++)
29		{
30			if (idx == 0)
31				x = (content[i] & 0xff) << 16;
32			else if (idx == 1)
33				x = x | ((content[i] & 0xff) << 8);
34			else
35				x = x | (content[i] & 0xff);
36
37			idx++;
38
39			if (idx == 3)
40			{
41				cw.write(alphabet[x >> 18]);
42				cw.write(alphabet[(x >> 12) & 0x3f]);
43				cw.write(alphabet[(x >> 6) & 0x3f]);
44				cw.write(alphabet[x & 0x3f]);
45
46				idx = 0;
47			}
48		}
49
50		if (idx == 1)
51		{
52			cw.write(alphabet[x >> 18]);
53			cw.write(alphabet[(x >> 12) & 0x3f]);
54			cw.write('=');
55			cw.write('=');
56		}
57
58		if (idx == 2)
59		{
60			cw.write(alphabet[x >> 18]);
61			cw.write(alphabet[(x >> 12) & 0x3f]);
62			cw.write(alphabet[(x >> 6) & 0x3f]);
63			cw.write('=');
64		}
65
66		return cw.toCharArray();
67	}
68
69	public static byte[] decode(char[] message) throws IOException
70	{
71		byte buff[] = new byte[4];
72		byte dest[] = new byte[message.length];
73
74		int bpos = 0;
75		int destpos = 0;
76
77		for (int i = 0; i < message.length; i++)
78		{
79			int c = message[i];
80
81			if ((c == '\n') || (c == '\r') || (c == ' ') || (c == '\t'))
82				continue;
83
84			if ((c >= 'A') && (c <= 'Z'))
85			{
86				buff[bpos++] = (byte) (c - 'A');
87			}
88			else if ((c >= 'a') && (c <= 'z'))
89			{
90				buff[bpos++] = (byte) ((c - 'a') + 26);
91			}
92			else if ((c >= '0') && (c <= '9'))
93			{
94				buff[bpos++] = (byte) ((c - '0') + 52);
95			}
96			else if (c == '+')
97			{
98				buff[bpos++] = 62;
99			}
100			else if (c == '/')
101			{
102				buff[bpos++] = 63;
103			}
104			else if (c == '=')
105			{
106				buff[bpos++] = 64;
107			}
108			else
109			{
110				throw new IOException("Illegal char in base64 code.");
111			}
112
113			if (bpos == 4)
114			{
115				bpos = 0;
116
117				if (buff[0] == 64)
118					break;
119
120				if (buff[1] == 64)
121					throw new IOException("Unexpected '=' in base64 code.");
122
123				if (buff[2] == 64)
124				{
125					int v = (((buff[0] & 0x3f) << 6) | ((buff[1] & 0x3f)));
126					dest[destpos++] = (byte) (v >> 4);
127					break;
128				}
129				else if (buff[3] == 64)
130				{
131					int v = (((buff[0] & 0x3f) << 12) | ((buff[1] & 0x3f) << 6) | ((buff[2] & 0x3f)));
132					dest[destpos++] = (byte) (v >> 10);
133					dest[destpos++] = (byte) (v >> 2);
134					break;
135				}
136				else
137				{
138					int v = (((buff[0] & 0x3f) << 18) | ((buff[1] & 0x3f) << 12) | ((buff[2] & 0x3f) << 6) | ((buff[3] & 0x3f)));
139					dest[destpos++] = (byte) (v >> 16);
140					dest[destpos++] = (byte) (v >> 8);
141					dest[destpos++] = (byte) (v);
142				}
143			}
144		}
145
146		byte[] res = new byte[destpos];
147		System.arraycopy(dest, 0, res, 0, destpos);
148
149		return res;
150	}
151}
152