1 57 58 package org.objectweb.cjdbc.common.stream.encoding; 59 60 72 public final class Base64 73 { 74 private static final int BASELENGTH = 255; 75 private static final int LOOKUPLENGTH = 64; 76 private static final int TWENTYFOURBITGROUP = 24; 77 private static final int EIGHTBIT = 8; 78 private static final int SIXTEENBIT = 16; 79 private static final int FOURBYTE = 4; 80 private static final int SIGN = -128; 81 private static final char PAD = '='; 82 private static final boolean F_DEBUG = false; 83 private static final byte[] BASE64_ALPHABET = new byte[BASELENGTH]; 84 private static final char[] LOOKUP_BASE64_ALPHABET = new char[LOOKUPLENGTH]; 85 86 static 87 { 88 89 for (int i = 0; i < BASELENGTH; i++) 90 { 91 BASE64_ALPHABET[i] = -1; 92 } 93 for (int i = 'Z'; i >= 'A'; i--) 94 { 95 BASE64_ALPHABET[i] = (byte) (i - 'A'); 96 } 97 for (int i = 'z'; i >= 'a'; i--) 98 { 99 BASE64_ALPHABET[i] = (byte) (i - 'a' + 26); 100 } 101 102 for (int i = '9'; i >= '0'; i--) 103 { 104 BASE64_ALPHABET[i] = (byte) (i - '0' + 52); 105 } 106 107 BASE64_ALPHABET['+'] = 62; 108 BASE64_ALPHABET['/'] = 63; 109 110 for (int i = 0; i <= 25; i++) 111 LOOKUP_BASE64_ALPHABET[i] = (char) ('A' + i); 112 113 for (int i = 26, j = 0; i <= 51; i++, j++) 114 LOOKUP_BASE64_ALPHABET[i] = (char) ('a' + j); 115 116 for (int i = 52, j = 0; i <= 61; i++, j++) 117 LOOKUP_BASE64_ALPHABET[i] = (char) ('0' + j); 118 LOOKUP_BASE64_ALPHABET[62] = '+'; 119 LOOKUP_BASE64_ALPHABET[63] = '/'; 120 } 121 122 protected static boolean isWhiteSpace(char octect) 123 { 124 return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); 125 } 126 127 protected static boolean isPad(char octect) 128 { 129 return (octect == PAD); 130 } 131 132 protected static boolean isData(char octect) 133 { 134 return (BASE64_ALPHABET[octect] != -1); 135 } 136 137 protected static boolean isBase64(char octect) 138 { 139 return (isWhiteSpace(octect) || isPad(octect) || isData(octect)); 140 } 141 142 148 public static String encode(byte[] binaryData) 149 { 150 151 if (binaryData == null) 152 return null; 153 154 int lengthDataBits = binaryData.length * EIGHTBIT; 155 if (lengthDataBits == 0) 156 { 157 return ""; 158 } 159 160 int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; 161 int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; 162 int numberQuartet = fewerThan24bits != 0 163 ? numberTriplets + 1 164 : numberTriplets; 165 int numberLines = (numberQuartet - 1) / 19 + 1; 166 char[] encodedData = null; 167 168 encodedData = new char[numberQuartet * 4 + numberLines]; 169 170 byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; 171 172 int encodedIndex = 0; 173 int dataIndex = 0; 174 int i = 0; 175 if (F_DEBUG) 176 { 177 System.out.println("number of triplets = " + numberTriplets); 178 } 179 180 for (int line = 0; line < numberLines - 1; line++) 181 { 182 for (int quartet = 0; quartet < 19; quartet++) 183 { 184 b1 = binaryData[dataIndex++]; 185 b2 = binaryData[dataIndex++]; 186 b3 = binaryData[dataIndex++]; 187 188 if (F_DEBUG) 189 { 190 System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3); 191 } 192 193 l = (byte) (b2 & 0x0f); 194 k = (byte) (b1 & 0x03); 195 196 byte val1 = ((b1 & SIGN) == 0) 197 ? (byte) (b1 >> 2) 198 : (byte) ((b1) >> 2 ^ 0xc0); 199 200 byte val2 = ((b2 & SIGN) == 0) 201 ? (byte) (b2 >> 4) 202 : (byte) ((b2) >> 4 ^ 0xf0); 203 byte val3 = ((b3 & SIGN) == 0) 204 ? (byte) (b3 >> 6) 205 : (byte) ((b3) >> 6 ^ 0xfc); 206 207 if (F_DEBUG) 208 { 209 System.out.println("val2 = " + val2); 210 System.out.println("k4 = " + (k << 4)); 211 System.out.println("vak = " + (val2 | (k << 4))); 212 } 213 214 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val1]; 215 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val2 | (k << 4)]; 216 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[(l << 2) | val3]; 217 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[b3 & 0x3f]; 218 219 i++; 220 } 221 encodedData[encodedIndex++] = 0xa; 222 } 223 224 for (; i < numberTriplets; i++) 225 { 226 b1 = binaryData[dataIndex++]; 227 b2 = binaryData[dataIndex++]; 228 b3 = binaryData[dataIndex++]; 229 230 if (F_DEBUG) 231 { 232 System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3); 233 } 234 235 l = (byte) (b2 & 0x0f); 236 k = (byte) (b1 & 0x03); 237 238 byte val1 = ((b1 & SIGN) == 0) 239 ? (byte) (b1 >> 2) 240 : (byte) ((b1) >> 2 ^ 0xc0); 241 242 byte val2 = ((b2 & SIGN) == 0) 243 ? (byte) (b2 >> 4) 244 : (byte) ((b2) >> 4 ^ 0xf0); 245 byte val3 = ((b3 & SIGN) == 0) 246 ? (byte) (b3 >> 6) 247 : (byte) ((b3) >> 6 ^ 0xfc); 248 249 if (F_DEBUG) 250 { 251 System.out.println("val2 = " + val2); 252 System.out.println("k4 = " + (k << 4)); 253 System.out.println("vak = " + (val2 | (k << 4))); 254 } 255 256 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val1]; 257 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val2 | (k << 4)]; 258 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[(l << 2) | val3]; 259 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[b3 & 0x3f]; 260 } 261 262 if (fewerThan24bits == EIGHTBIT) 264 { 265 b1 = binaryData[dataIndex]; 266 k = (byte) (b1 & 0x03); 267 if (F_DEBUG) 268 { 269 System.out.println("b1=" + b1); 270 System.out.println("b1<<2 = " + (b1 >> 2)); 271 } 272 byte val1 = ((b1 & SIGN) == 0) 273 ? (byte) (b1 >> 2) 274 : (byte) ((b1) >> 2 ^ 0xc0); 275 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val1]; 276 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[k << 4]; 277 encodedData[encodedIndex++] = PAD; 278 encodedData[encodedIndex++] = PAD; 279 } 280 else if (fewerThan24bits == SIXTEENBIT) 281 { 282 b1 = binaryData[dataIndex]; 283 b2 = binaryData[dataIndex + 1]; 284 l = (byte) (b2 & 0x0f); 285 k = (byte) (b1 & 0x03); 286 287 byte val1 = ((b1 & SIGN) == 0) 288 ? (byte) (b1 >> 2) 289 : (byte) ((b1) >> 2 ^ 0xc0); 290 byte val2 = ((b2 & SIGN) == 0) 291 ? (byte) (b2 >> 4) 292 : (byte) ((b2) >> 4 ^ 0xf0); 293 294 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val1]; 295 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[val2 | (k << 4)]; 296 encodedData[encodedIndex++] = LOOKUP_BASE64_ALPHABET[l << 2]; 297 encodedData[encodedIndex++] = PAD; 298 } 299 300 encodedData[encodedIndex] = 0xa; 301 302 return new String (encodedData); 303 } 304 305 311 public static byte[] decode(String encoded) 312 { 313 314 if (encoded == null) 315 return null; 316 317 char[] base64Data = encoded.toCharArray(); 318 int len = removeWhiteSpace(base64Data); 320 321 if (len % FOURBYTE != 0) 322 { 323 return null; } 325 326 int numberQuadruple = (len / FOURBYTE); 327 328 if (numberQuadruple == 0) 329 return new byte[0]; 330 331 byte[] decodedData = null; 332 byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; 333 char d1 = 0, d2 = 0, d3 = 0, d4 = 0; 334 335 int i = 0; 336 int encodedIndex = 0; 337 int dataIndex = 0; 338 decodedData = new byte[(numberQuadruple) * 3]; 339 340 for (; i < numberQuadruple - 1; i++) 341 { 342 d1 = base64Data[dataIndex++]; 343 d2 = base64Data[dataIndex++]; 344 d3 = base64Data[dataIndex++]; 345 d4 = base64Data[dataIndex++]; 346 if (!isData(d1) || !isData(d2) || !isData(d3) || !isData(d4)) 347 return null; 349 b1 = BASE64_ALPHABET[d1]; 350 b2 = BASE64_ALPHABET[d2]; 351 b3 = BASE64_ALPHABET[d3]; 352 b4 = BASE64_ALPHABET[d4]; 353 354 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); 355 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 356 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); 357 } 358 359 d1 = base64Data[dataIndex++]; 360 d2 = base64Data[dataIndex++]; 361 if (!isData(d1) || !isData(d2)) 362 { 363 return null; } 365 366 b1 = BASE64_ALPHABET[d1]; 367 b2 = BASE64_ALPHABET[d2]; 368 369 d3 = base64Data[dataIndex++]; 370 d4 = base64Data[dataIndex++]; 371 if (!isData((d3)) || !isData((d4))) 372 { if (isPad(d3) && isPad(d4)) 374 { if ((b2 & 0xf) != 0) return null; 377 byte[] tmp = new byte[i * 3 + 1]; 378 System.arraycopy(decodedData, 0, tmp, 0, i * 3); 379 tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); 380 return tmp; 381 } 382 else if (!isPad(d3) && isPad(d4)) 383 { b3 = BASE64_ALPHABET[d3]; 385 if ((b3 & 0x3) != 0) return null; 387 byte[] tmp = new byte[i * 3 + 2]; 388 System.arraycopy(decodedData, 0, tmp, 0, i * 3); 389 tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); 390 tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 391 return tmp; 392 } 393 else 394 { 395 return null; } 398 } 399 else 400 { b3 = BASE64_ALPHABET[d3]; 402 b4 = BASE64_ALPHABET[d4]; 403 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); 404 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 405 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); 406 407 } 408 409 return decodedData; 410 } 411 412 418 protected static int removeWhiteSpace(char[] data) 419 { 420 if (data == null) 421 return 0; 422 423 int newSize = 0; 425 int len = data.length; 426 for (int i = 0; i < len; i++) 427 { 428 if (!isWhiteSpace(data[i])) 429 data[newSize++] = data[i]; 430 } 431 return newSize; 432 } 433 } | Popular Tags |