1 package com.ca.commons.cbutil; 2 3 import java.io.UnsupportedEncodingException ; 4 5 16 17 public class CBBase64 18 { 19 20 21 43 44 47 48 private CBBase64() 49 { 50 } 51 52 59 public static String binaryToString(byte[] byteArray) 60 { 61 return binaryToString(byteArray, 0); 62 } 63 64 75 76 public static String binaryToString(byte[] byteArray, int offset) 77 { 78 if (byteArray == null) return null; 80 int arraySize = byteArray.length; 81 int thirdSize = arraySize / 3; 82 83 byte[] base64Data = encode(byteArray); 84 85 if (base64Data == null) return null; 87 return format(base64Data, offset); 88 89 } 90 91 100 101 103 public static String format(byte[] base64Data, int offset) 104 { 105 106 String data; 107 try 108 { 109 data = new String (base64Data, "US-ASCII"); 110 } 111 catch (Exception e) 112 { 113 data = new String (base64Data); } 115 116 119 StringBuffer buffer = new StringBuffer (data); 120 121 int i = 76 - offset; 122 while (i < base64Data.length) 123 { 124 buffer.insert(i, "\r\n "); 125 i += 78; 126 } 127 128 return buffer.toString(); 129 } 130 131 140 141 public static byte[] encode(byte[] byteArray) 142 { 143 try 144 { 145 int arraySize = byteArray.length; 146 147 int outputSize = (arraySize % 3 == 0) ? (arraySize / 3) * 4 : ((arraySize / 3) + 1) * 4; 148 149 byte[] output = new byte[outputSize]; 150 151 153 int bufferLength = 0; 154 155 for (int i = 0; i <= (arraySize - 3); i += 3) 156 { 157 convertTriplet(byteArray[i], byteArray[i + 1], byteArray[i + 2], 3, output, bufferLength); 158 bufferLength += 4; 159 } 160 161 switch (arraySize % 3) 162 { 163 case 0: 164 break; 165 166 case 1: 167 convertTriplet(byteArray[arraySize - 1], (byte) 0, (byte) 0, 1, output, bufferLength); 168 break; 169 170 case 2: 171 convertTriplet(byteArray[arraySize - 2], byteArray[arraySize - 1], (byte) 0, 2, output, bufferLength); 172 break; 173 } 174 175 return output; 176 } 177 catch (CBBase64EncodingException e) 178 { 179 return null; 180 } 181 } 182 183 195 196 public static byte[] encodeFormatted(byte[] byteArray, int start, int colSize) 197 throws CBBase64EncodingException 198 { 199 try 200 { 201 if (colSize % 4 != 0) 202 { 203 throw new CBBase64EncodingException("error in encodeFormatted - colSize not a multiple of 4."); 204 } 205 206 if (start >= colSize) 207 { 208 throw new CBBase64EncodingException("error in encodeFormatted - start is not less than colSize."); 209 } 210 211 int arraySize = byteArray.length; 212 213 int outputSize = start + ((arraySize % 3 == 0) ? (arraySize / 3) * 4 : ((arraySize / 3) + 1) * 4); 214 215 outputSize += (outputSize / colSize) + 1; 217 byte[] output = new byte[outputSize]; 218 219 221 for (int i = 0; i < start; i++) 222 output[i] = (byte) ' '; 224 int bufferLength = start; 225 226 for (int i = 0; i <= (arraySize - 3); i += 3) 227 { 228 convertTriplet(byteArray[i], byteArray[i + 1], byteArray[i + 2], 3, output, bufferLength); 229 bufferLength += 4; 230 231 if (bufferLength % (colSize + 1) == colSize) { 233 output[bufferLength++] = (byte) '\n'; 234 } 235 } 236 237 switch (arraySize % 3) 238 { 239 case 0: 240 break; 241 242 case 1: 243 convertTriplet(byteArray[arraySize - 1], (byte) 0, (byte) 0, 1, output, bufferLength); 244 bufferLength += 4; 245 break; 246 247 case 2: 248 convertTriplet(byteArray[arraySize - 2], byteArray[arraySize - 1], (byte) 0, 2, output, bufferLength); 249 bufferLength += 4; 250 break; 251 } 252 253 if (bufferLength < outputSize) { 256 output[bufferLength++] = (byte) '\n'; 257 } 258 else 259 { 260 System.err.println("wierdness in formatted base 64 : bufferlength (" + bufferLength + ") != 1 + outputsize (" + outputSize + ")"); 261 } 262 263 return output; 264 } 265 catch (CBBase64EncodingException e) 266 { 267 return null; 269 } 270 catch (Exception e2) 271 { 272 System.err.println("unexpected error in base 64 encoding"); 273 e2.printStackTrace(); 274 return null; 275 } 276 } 277 278 279 286 287 public static byte[] stringToBinary(String chars) 288 { 289 if (chars == null) return null; 290 291 byte charArray[]; 292 293 try 294 { 295 charArray = chars.getBytes("US-ASCII"); 296 } 297 catch (UnsupportedEncodingException e) 298 { 299 charArray = chars.getBytes(); 300 } 301 302 return decode(charArray); 303 } 304 305 306 313 314 public static byte[] decode(byte[] rawData) 315 { 316 try 317 { 318 319 int resultLength = (int) (rawData.length * .75); 321 byte result[] = new byte[resultLength]; 322 323 int noBytesWritten = 0; 324 int validCharacters = 0; 325 326 byte c; 327 byte quad[] = new byte[4]; int bytes; int numfound = 0; 331 332 334 for (int i = 0; i < rawData.length; i++) 335 { 336 c = rawData[i]; 337 if ((c >= (byte) 'A' && c <= (byte) 'Z') || (c >= (byte) 'a' && c <= (byte) 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == (byte) '/') || (c == (byte) '=')) 338 { 339 quad[numfound++] = c; 340 validCharacters++; 341 } 342 else if (" \r\n\t\f".indexOf((char) c) == -1) 343 { 344 return null; 346 } 347 348 351 if (numfound == 4) 352 { 353 bytes = convertQuad(quad); 354 result[noBytesWritten++] = (byte) ((bytes & 0xFF0000) >> 16); 355 if (c != '=') 356 { 357 result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8); 358 result[noBytesWritten++] = (byte) (bytes & 0xFF); 359 } 360 else if (rawData[i - 1] != '=') 361 { 362 result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8); 363 if ((bytes & 0xFF) > 0) 364 { 365 return null; 367 } 368 } 369 else if ((bytes & 0xFF00) > 0) 370 { 371 return null; 373 } 374 375 numfound = 0; 376 } 377 } 378 379 382 if (validCharacters % 4 != 0) 383 { 384 return null; 386 } 387 388 389 byte finalResult[] = new byte[noBytesWritten]; 390 System.arraycopy(result, 0, finalResult, 0, noBytesWritten); 391 return finalResult; 392 } 393 catch (Exception e) 394 { 395 return null; 397 } 398 399 } 400 401 408 409 public static byte[] decode(String chars) 410 throws CBBase64EncodingException 411 { 412 413 if (chars == null) return null; 414 415 byte rawData[]; 416 417 try 418 { 419 rawData = chars.getBytes("US-ASCII"); 420 } 421 catch (UnsupportedEncodingException e) 422 { 423 throw new CBBase64EncodingException("unable to convert base64 encoded data to bytes using US-ASCII encoding", e); 424 } 425 426 int resultLength = (int) (rawData.length * .75); 428 byte result[] = new byte[resultLength]; 429 430 int noBytesWritten = 0; 431 int validCharacters = 0; 432 433 byte c; 434 byte quad[] = new byte[4]; int bytes; int numfound = 0; 438 439 441 for (int i = 0; i < rawData.length; i++) 442 { 443 c = rawData[i]; 444 if ((c >= (byte) 'A' && c <= (byte) 'Z') || (c >= (byte) 'a' && c <= (byte) 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == (byte) '/') || (c == (byte) '=')) 445 { 446 quad[numfound++] = c; 447 validCharacters++; 448 } 449 else if (" \r\n\t\f".indexOf((char) c) == -1) 450 { 451 throw new CBBase64EncodingException("error... bad character (" + (char) c + ") read from base64 encoded string"); 452 } 453 454 457 if (numfound == 4) 458 { 459 bytes = convertQuad(quad); 460 result[noBytesWritten++] = (byte) ((bytes & 0xFF0000) >> 16); 461 if (c != '=') 462 { 463 result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8); 464 result[noBytesWritten++] = (byte) (bytes & 0xFF); 465 } 466 else if (rawData[i - 1] != '=') 467 { 468 result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8); 469 if ((bytes & 0xFF) > 0) 470 { 471 throw new CBBase64EncodingException("Warning: Corrupt base64 Encoded Data - contains trailing bits after end of base 64 data."); 472 } 473 } 474 else if ((bytes & 0xFF00) > 0) 475 { 476 throw new CBBase64EncodingException("Warning: Corrupt base64 Encoded File - contains trailing bits after end of base64 data."); 477 } 478 479 numfound = 0; 480 } 481 } 482 483 486 if (validCharacters % 4 != 0) 487 { 488 throw new CBBase64EncodingException("Warning: Corrupt base64 Encoded Data - Length (" + validCharacters + ") of valid characters not divisible by 4."); 489 } 490 491 492 byte finalResult[] = new byte[noBytesWritten]; 493 System.arraycopy(result, 0, finalResult, 0, noBytesWritten); 494 return finalResult; 495 496 } 497 498 499 511 512 private static void convertTriplet(byte a, byte b, byte c, int Num, byte[] buff, int buffpos) 513 throws CBBase64EncodingException 514 { 515 byte w, x, y, z; int trip = (a << 16) | ((b << 8) & 0xFF00) | (c & 0xFF); 517 518 w = (byte) ((trip & 0xFC0000) >> 18); 519 x = (byte) ((trip & 0x03F000) >> 12); 520 y = (byte) ((trip & 0x000FC0) >> 6); 521 z = (byte) (trip & 0x00003F); 522 523 buff[buffpos] = convertFrom6Bit(w); 524 buff[buffpos + 1] = convertFrom6Bit(x); 525 526 if (Num == 1) 527 { 528 buff[buffpos + 2] = (byte) '='; 529 buff[buffpos + 3] = (byte) '='; 530 } 531 else 532 { 533 buff[buffpos + 2] = convertFrom6Bit(y); 534 535 if (Num == 2) 536 { 537 buff[buffpos + 3] = (byte) '='; 538 } 539 else 540 { 541 buff[buffpos + 3] = convertFrom6Bit(z); 542 } 543 } 544 } 545 546 553 554 556 private static byte convertFrom6Bit(byte b) 557 throws CBBase64EncodingException 558 { 559 byte c; 560 561 if (b < 26) 562 return (byte) ('A' + b); else if (b < 52) 564 return (byte) (('a' - 26) + b); else if (b < 62) 566 return (byte) (('0' - 52) + b); else if (b == 62) 568 return ((byte) '+'); 569 else if (b == 63) 570 return ((byte) '/'); 571 else { 573 throw new CBBase64EncodingException("erroroneous value " + (char) b + " passed in convertFrom6bit"); 574 } 575 } 576 577 584 585 private static byte convertTo6Bit(byte c) 586 throws CBBase64EncodingException 587 { 588 if (c == (byte) '+') 589 return 62; 590 else if (c == (byte) '/') 591 return 63; 592 else if (c == (byte) '=') return 0; 594 else if (c <= (byte) '9') 595 return (byte) (c - (byte) '0' + 52); 596 else if (c <= (byte) 'Z') 597 return (byte) (c - (byte) 'A'); 598 else if (c <= (byte) 'z') 599 return (byte) (c - (byte) 'a' + 26); 600 else { 602 throw new CBBase64EncodingException("erroroneous value " + (char) c + " passed in convertTo6bit"); 603 } 604 } 605 606 613 614 private static int convertQuad(byte[] quad) 615 throws CBBase64EncodingException 616 { 617 byte a = convertTo6Bit(quad[0]); 618 byte b = convertTo6Bit(quad[1]); 619 byte c = convertTo6Bit(quad[2]); 620 byte d = convertTo6Bit(quad[3]); 621 622 int ret = (a << 18) + (b << 12) + (c << 6) + d; 623 624 return ret; 625 } 626 } | Popular Tags |