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