107
108 /**
109 * This array is a lookup table that translates 6-bit positive integer
110 * index values into their "Alternate Base64 Alphabet" equivalents.
111 * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
112 * This alternate alphabet does not use the capital letters. It is
113 * designed for use in environments where "case folding" occurs.
114 */
115 private static final char intToAltBase64[] = {
116 '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':',
117 ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~',
118 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
119 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
120 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?'
121 };
122
123 /**
124 * Translates the specified Base64 string (as per Preferences.get(byte[]))
125 * into a byte array.
126 *
127 * @throw IllegalArgumentException if {@code s} is not a valid Base64
128 * string.
129 */
130 static byte[] base64ToByteArray(String s) {
131 return base64ToByteArray(s, false);
132 }
133
134 /**
135 * Translates the specified "alternate representation" Base64 string
136 * into a byte array.
137 *
138 * @throw IllegalArgumentException or ArrayOutOfBoundsException
139 * if {@code s} is not a valid alternate representation
140 * Base64 string.
141 */
142 static byte[] altBase64ToByteArray(String s) {
143 return base64ToByteArray(s, true);
144 }
145
146 private static byte[] base64ToByteArray(String s, boolean alternate) {
147 byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
148 int sLen = s.length();
149 int numGroups = sLen/4;
150 if (4*numGroups != sLen)
151 throw new IllegalArgumentException(
152 "String length must be a multiple of four.");
153 int missingBytesInLastGroup = 0;
154 int numFullGroups = numGroups;
155 if (sLen != 0) {
156 if (s.charAt(sLen-1) == '=') {
157 missingBytesInLastGroup++;
158 numFullGroups--;
177 // Translate partial group, if present
178 if (missingBytesInLastGroup != 0) {
179 int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
180 int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
181 result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
182
183 if (missingBytesInLastGroup == 1) {
184 int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
185 result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
186 }
187 }
188 // assert inCursor == s.length()-missingBytesInLastGroup;
189 // assert outCursor == result.length;
190 return result;
191 }
192
193 /**
194 * Translates the specified character, which is assumed to be in the
195 * "Base 64 Alphabet" into its equivalent 6-bit positive integer.
196 *
197 * @throw IllegalArgumentException or ArrayOutOfBoundsException if
198 * c is not in the Base64 Alphabet.
199 */
200 private static int base64toInt(char c, byte[] alphaToInt) {
201 int result = alphaToInt[c];
202 if (result < 0)
203 throw new IllegalArgumentException("Illegal character " + c);
204 return result;
205 }
206
207 /**
208 * This array is a lookup table that translates unicode characters
209 * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
210 * into their 6-bit positive integer equivalents. Characters that
211 * are not in the Base64 alphabet but fall within the bounds of the
212 * array are translated to -1.
213 */
214 private static final byte base64ToInt[] = {
215 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
216 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
217 -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
|
107
108 /**
109 * This array is a lookup table that translates 6-bit positive integer
110 * index values into their "Alternate Base64 Alphabet" equivalents.
111 * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
112 * This alternate alphabet does not use the capital letters. It is
113 * designed for use in environments where "case folding" occurs.
114 */
115 private static final char intToAltBase64[] = {
116 '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':',
117 ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~',
118 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
119 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
120 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?'
121 };
122
123 /**
124 * Translates the specified Base64 string (as per Preferences.get(byte[]))
125 * into a byte array.
126 *
127 * @throws IllegalArgumentException if {@code s} is not a valid Base64
128 * string.
129 */
130 static byte[] base64ToByteArray(String s) {
131 return base64ToByteArray(s, false);
132 }
133
134 /**
135 * Translates the specified "alternate representation" Base64 string
136 * into a byte array.
137 *
138 * @throws IllegalArgumentException or ArrayOutOfBoundsException
139 * if {@code s} is not a valid alternate representation
140 * Base64 string.
141 */
142 static byte[] altBase64ToByteArray(String s) {
143 return base64ToByteArray(s, true);
144 }
145
146 private static byte[] base64ToByteArray(String s, boolean alternate) {
147 byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
148 int sLen = s.length();
149 int numGroups = sLen/4;
150 if (4*numGroups != sLen)
151 throw new IllegalArgumentException(
152 "String length must be a multiple of four.");
153 int missingBytesInLastGroup = 0;
154 int numFullGroups = numGroups;
155 if (sLen != 0) {
156 if (s.charAt(sLen-1) == '=') {
157 missingBytesInLastGroup++;
158 numFullGroups--;
177 // Translate partial group, if present
178 if (missingBytesInLastGroup != 0) {
179 int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
180 int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
181 result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
182
183 if (missingBytesInLastGroup == 1) {
184 int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
185 result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
186 }
187 }
188 // assert inCursor == s.length()-missingBytesInLastGroup;
189 // assert outCursor == result.length;
190 return result;
191 }
192
193 /**
194 * Translates the specified character, which is assumed to be in the
195 * "Base 64 Alphabet" into its equivalent 6-bit positive integer.
196 *
197 * @throws IllegalArgumentException or ArrayOutOfBoundsException if
198 * c is not in the Base64 Alphabet.
199 */
200 private static int base64toInt(char c, byte[] alphaToInt) {
201 int result = alphaToInt[c];
202 if (result < 0)
203 throw new IllegalArgumentException("Illegal character " + c);
204 return result;
205 }
206
207 /**
208 * This array is a lookup table that translates unicode characters
209 * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
210 * into their 6-bit positive integer equivalents. Characters that
211 * are not in the Base64 alphabet but fall within the bounds of the
212 * array are translated to -1.
213 */
214 private static final byte base64ToInt[] = {
215 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
216 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
217 -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
|