]>
Commit | Line | Data |
---|---|---|
bde1652c | 1 | package mit.moira; |
2 | ||
3 | import java.util.Vector; | |
4 | import java.util.Enumeration; | |
5 | ||
6 | /** | |
7 | * Class with static functions for base64 encoding and decoding as well | |
8 | * as other utilities. | |
9 | */ | |
10 | ||
11 | public class Coder { | |
12 | static final char encv[] = { | |
13 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | |
14 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | |
15 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | |
16 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |
17 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; | |
18 | static char x2c (char [] what, int off) { | |
19 | int digit; | |
20 | digit = (what[off] >= 'A' ? ((what[off] & 0xdf) - 'A')+10 : (what[off] - '0')); | |
21 | digit *= 16; | |
22 | digit += (what[off+1] >= 'A' ? ((what[off+1] & 0xdf) - 'A')+10 : (what[off+1] - '0')); | |
23 | return((char)digit); | |
24 | } | |
25 | ||
26 | private Coder() { // No Constructors... | |
27 | } | |
28 | ||
29 | /** | |
30 | * Remove URL escape sequences | |
31 | * | |
32 | * @param aurl A String with potential embedded escapes. | |
33 | * @return the String with the escapes removed. | |
34 | */ | |
35 | public static String unescape_url(String aurl) { | |
36 | int x, y, i; | |
37 | char [] url = new char [aurl.length()]; | |
38 | aurl.getChars(0, aurl.length(), url, 0); | |
39 | StringBuffer ret = new StringBuffer(); | |
40 | for (i = 0; i < url.length; i++) { | |
41 | if (url[i] == '%') { | |
42 | ret.append(x2c(url, i+1)); | |
43 | i += 2; | |
44 | } else if (url[i] == '+') { | |
45 | ret.append(' '); | |
46 | } else ret.append(url[i]); | |
47 | } | |
48 | return (new String(ret)); | |
49 | } | |
50 | ||
51 | /** | |
52 | * Encodes a byte array in base64 characters and returns the result | |
53 | * as a String. | |
54 | * | |
55 | * @param data the Byte array | |
56 | * @return The encoded string | |
57 | */ | |
58 | ||
59 | public static String encode(byte [] data) { | |
60 | StringBuffer ret = new StringBuffer(); | |
61 | int len = data.length; | |
62 | int c; | |
63 | int p = 0; | |
64 | int i = 0; | |
65 | int nib1, nib2, nib3, nib4; | |
66 | while (i < len) { | |
67 | if ((i+3) <= len) { | |
68 | c = (data[i++] & 0xFF); | |
69 | c = (c << 8) | (data[i++] & 0xFF); | |
70 | c = (c << 8) | (data[i++] & 0xFF); | |
71 | nib1 = (c & 0x0FC0000) >>> 18; | |
72 | nib2 = (c & 0x003F000) >>> 12; | |
73 | nib3 = (c & 0x0000FC0) >>> 6; | |
74 | nib4 = (c & 0x000003F); | |
75 | ret.append(encv[nib1]); | |
76 | ret.append(encv[nib2]); | |
77 | ret.append(encv[nib3]); | |
78 | ret.append(encv[nib4]); | |
79 | } else { | |
80 | p = len - i; | |
81 | c = data[i++]; | |
82 | c = c << 8; | |
83 | if (p > 1) c |= (data[i++] & 0xFF); | |
84 | c = c << 8; | |
85 | if (p > 2) c |= (data[i++] & 0xFF); // Should never happen | |
86 | nib1 = (c & 0x0FC0000) >>> 18; | |
87 | nib2 = (c & 0x003F000) >>> 12; | |
88 | nib3 = (c & 0x0000FC0) >>> 6; | |
89 | nib4 = (c & 0x000003F); | |
90 | ret.append(encv[nib1]); | |
91 | ret.append(encv[nib2]); | |
92 | if (p == 1) ret.append('='); | |
93 | else ret.append(encv[nib3]); | |
94 | ret.append('='); | |
95 | } | |
96 | } | |
97 | return (new String(ret)); | |
98 | } | |
99 | ||
100 | /** | |
101 | * Decodes a base64 encoded string and returns the decoded value | |
102 | * in a byte array. | |
103 | * | |
104 | * @param s The base64 encoded string | |
105 | * @return the byte array decoded | |
106 | */ | |
107 | public static byte [] decode (String s) { | |
108 | Vector v = new Vector(); | |
109 | int p = 0; | |
110 | int i = 0; | |
111 | int k = 0; | |
112 | int z = 0; | |
113 | int reg = 0; | |
114 | for (i = 0; i < s.length(); i++) { | |
115 | char c = s.charAt(i); | |
116 | if (c == '/') z = 63; | |
117 | else if (c == '+') z = 62; | |
118 | else if ((c >= 'a') && (c <= 'z')) z = (c - 'a') + 26; | |
119 | else if ((c >= 'A') && (c <= 'Z')) z = (c - 'A'); | |
120 | else if ((c >= '0') && (c <= '9')) z = (c - '0') + 52; | |
121 | else if (c == '=') { | |
122 | p++; | |
123 | z = 0; | |
124 | } else continue; | |
125 | reg <<= 6; | |
126 | reg += z; | |
127 | k++; | |
128 | if (k == 4) { | |
129 | for (z = 0; z < 3; z++) { | |
130 | v.addElement(new Integer((reg & 0xff0000) >>> 16)); | |
131 | reg = (reg << 8); | |
132 | } | |
133 | k = 0; | |
134 | } | |
135 | } | |
136 | Enumeration e = v.elements(); | |
137 | byte [] retval = new byte[v.size() - p]; | |
138 | for(i = 0; i < v.size() - p; i++) { | |
139 | retval[i] = ((Integer) e.nextElement()).byteValue(); | |
140 | } | |
141 | return (retval); | |
142 | } | |
143 | } | |
144 | ||
145 | ||
146 |