1 18 package com.Ostermiller.util; 19 20 import java.io.*; 21 import gnu.getopt.*; 22 import java.text.MessageFormat ; 23 import java.util.ResourceBundle ; 24 import java.util.Locale ; 25 26 143 public class Base64 { 144 145 150 private static final int END_OF_INPUT = -1; 151 152 157 private static final int NON_BASE_64 = -1; 158 159 164 private static final int NON_BASE_64_WHITESPACE = -2; 165 166 171 private static final int NON_BASE_64_PADDING = -3; 172 173 178 private Base64(){ 179 } 180 181 187 protected static final byte[] base64Chars = { 188 'A','B','C','D','E','F','G','H', 189 'I','J','K','L','M','N','O','P', 190 'Q','R','S','T','U','V','W','X', 191 'Y','Z','a','b','c','d','e','f', 192 'g','h','i','j','k','l','m','n', 193 'o','p','q','r','s','t','u','v', 194 'w','x','y','z','0','1','2','3', 195 '4','5','6','7','8','9','+','/', 196 }; 197 198 205 protected static final byte[] reverseBase64Chars = new byte[0x100]; 206 static { 207 for (int i=0; i<reverseBase64Chars.length; i++){ 209 reverseBase64Chars[i] = NON_BASE_64; 210 } 211 for (byte i=0; i < base64Chars.length; i++){ 214 reverseBase64Chars[base64Chars[i]] = i; 215 } 216 reverseBase64Chars[' '] = NON_BASE_64_WHITESPACE; 217 reverseBase64Chars['\n'] = NON_BASE_64_WHITESPACE; 218 reverseBase64Chars['\r'] = NON_BASE_64_WHITESPACE; 219 reverseBase64Chars['\t'] = NON_BASE_64_WHITESPACE; 220 reverseBase64Chars['\f'] = NON_BASE_64_WHITESPACE; 221 reverseBase64Chars['='] = NON_BASE_64_PADDING; 222 } 223 224 229 public static final String version = "1.2"; 230 231 236 protected static ResourceBundle labels = ResourceBundle.getBundle("com.Ostermiller.util.Base64", Locale.getDefault()); 237 238 private static final int ACTION_GUESS = 0; 239 private static final int ACTION_ENCODE = 1; 240 private static final int ACTION_DECODE = 2; 241 242 private static final int ARGUMENT_GUESS = 0; 243 private static final int ARGUMENT_STRING = 1; 244 private static final int ARGUMENT_FILE = 2; 245 246 254 public static void main(String [] args){ 255 LongOpt[] longopts = { 257 new LongOpt(labels.getString("help.option"), LongOpt.NO_ARGUMENT, null, 1), 258 new LongOpt(labels.getString("version.option"), LongOpt.NO_ARGUMENT, null, 2), 259 new LongOpt(labels.getString("about.option"), LongOpt.NO_ARGUMENT, null, 3), 260 new LongOpt(labels.getString("encode.option"), LongOpt.NO_ARGUMENT, null, 'e'), 261 new LongOpt(labels.getString("lines.option"), LongOpt.NO_ARGUMENT, null, 'l'), 262 new LongOpt(labels.getString("nolines.option"), LongOpt.NO_ARGUMENT, null, 6), 263 new LongOpt(labels.getString("decode.option"), LongOpt.NO_ARGUMENT, null, 'd'), 264 new LongOpt(labels.getString("decodeall.option"), LongOpt.NO_ARGUMENT, null, 'a'), 265 new LongOpt(labels.getString("decodegood.option"), LongOpt.NO_ARGUMENT, null, 5), 266 new LongOpt(labels.getString("guess.option"), LongOpt.NO_ARGUMENT, null, 'g'), 267 new LongOpt(labels.getString("ext.option"), LongOpt.OPTIONAL_ARGUMENT, null, 'x'), 268 new LongOpt(labels.getString("force.option"), LongOpt.NO_ARGUMENT, null, 'f'), 269 new LongOpt(labels.getString("quiet.option"), LongOpt.NO_ARGUMENT, null, 'q'), 270 new LongOpt(labels.getString("reallyquiet.option"), LongOpt.NO_ARGUMENT, null, 'Q'), 271 new LongOpt(labels.getString("verbose.option"), LongOpt.NO_ARGUMENT, null, 'v'), 272 new LongOpt(labels.getString("noforce.option"), LongOpt.NO_ARGUMENT, null, 4), 273 new LongOpt(labels.getString("file.option"), LongOpt.NO_ARGUMENT, null, 7), 274 new LongOpt(labels.getString("string.option"), LongOpt.NO_ARGUMENT, null, 8), 275 new LongOpt(labels.getString("newline.option"), LongOpt.NO_ARGUMENT, null, 'n'), 276 new LongOpt(labels.getString("nonewline.option"), LongOpt.NO_ARGUMENT, null, 9), 277 }; 278 String oneLetterOptions = "eldagx::fqQvVn"; 279 Getopt opts = new Getopt(labels.getString("base64"), args, oneLetterOptions, longopts); 280 int action = ACTION_GUESS; 281 String extension = "base64"; 282 boolean force = false; 283 boolean printMessages = true; 284 boolean printErrors = true; 285 boolean forceDecode = false; 286 boolean lineBreaks = true; 287 int argumentType = ARGUMENT_GUESS; 288 boolean decodeEndLine = false; 289 int c; 290 while ((c = opts.getopt()) != -1){ 291 switch(c){ 292 case 1:{ 293 String [] helpFlags = new String []{ 295 "--" + labels.getString("help.option"), 296 "--" + labels.getString("version.option"), 297 "--" + labels.getString("about.option"), 298 "-g --" + labels.getString("guess.option"), 299 "-e --" + labels.getString("encode.option"), 300 "-l --" + labels.getString("lines.option"), 301 "--" + labels.getString("nolines.option"), 302 "-d --" + labels.getString("decode.option"), 303 "-a --" + labels.getString("decodeall.option"), 304 "--" + labels.getString("decodegood.option"), 305 "-x --" + labels.getString("ext.option") + " <" + labels.getString("ext.option") + ">", 306 "-f --" + labels.getString("force.option"), 307 "--" + labels.getString("noforce.option"), 308 "-v --" + labels.getString("verbose.option"), 309 "-q --" + labels.getString("quiet.option"), 310 "-Q --" + labels.getString("reallyquiet.option"), 311 "--" + labels.getString("file.option"), 312 "--" + labels.getString("string.option"), 313 "-n --" + labels.getString("newline.option"), 314 "--" + labels.getString("nonewline.option"), 315 }; 316 int maxLength = 0; 317 for (int i=0; i<helpFlags.length; i++){ 318 maxLength = Math.max(maxLength, helpFlags[i].length()); 319 } 320 maxLength += 2; 321 System.out.println( 322 labels.getString("base64") + " [-" + StringHelper.replace(oneLetterOptions, ":", "") + "] <" + labels.getString("files") + ">\n" + 323 labels.getString("purpose.message") + "\n" + 324 " " + labels.getString("stdin.message") + "\n" + 325 " " + StringHelper.postpad(helpFlags[0] ,maxLength, ' ') + labels.getString("help.message") + "\n" + 326 " " + StringHelper.postpad(helpFlags[1] ,maxLength, ' ') + labels.getString("version.message") + "\n" + 327 " " + StringHelper.postpad(helpFlags[2] ,maxLength, ' ') + labels.getString("about.message") + "\n" + 328 " " + StringHelper.postpad(helpFlags[3] ,maxLength, ' ') + labels.getString("g.message") + " (" + labels.getString("default") + ")\n" + 329 " " + StringHelper.postpad(helpFlags[4] ,maxLength, ' ') + labels.getString("e.message") + "\n" + 330 " " + StringHelper.postpad(helpFlags[5] ,maxLength, ' ') + labels.getString("l.message") + " (" + labels.getString("default") + ")\n" + 331 " " + StringHelper.postpad(helpFlags[6] ,maxLength, ' ') + labels.getString("nolines.message") + "\n" + 332 " " + StringHelper.postpad(helpFlags[7] ,maxLength, ' ') + labels.getString("d.message") + "\n" + 333 " " + StringHelper.postpad(helpFlags[8] ,maxLength, ' ') + labels.getString("a.message") + "\n" + 334 " " + StringHelper.postpad(helpFlags[9] ,maxLength, ' ') + labels.getString("decodegood.message") + " (" + labels.getString("default") + ")\n" + 335 " " + StringHelper.postpad(helpFlags[10] ,maxLength, ' ') + labels.getString("x.message") + "\n" + 336 " " + StringHelper.postpad(helpFlags[11] ,maxLength, ' ') + labels.getString("f.message") + "\n" + 337 " " + StringHelper.postpad(helpFlags[12] ,maxLength, ' ') + labels.getString("noforce.message") + " (" + labels.getString("default") + ")\n" + 338 " " + StringHelper.postpad(helpFlags[13] ,maxLength, ' ') + labels.getString("v.message") + " (" + labels.getString("default") + ")\n" + 339 " " + StringHelper.postpad(helpFlags[14] ,maxLength, ' ') + labels.getString("q.message") + "\n" + 340 " " + StringHelper.postpad(helpFlags[15] ,maxLength, ' ') + labels.getString("Q.message") + "\n" + 341 " " + StringHelper.postpad(helpFlags[16] ,maxLength, ' ') + labels.getString("file.message") + "\n" + 342 " " + StringHelper.postpad(helpFlags[17] ,maxLength, ' ') + labels.getString("string.message") + "\n" + 343 " " + StringHelper.postpad(helpFlags[18] ,maxLength, ' ') + labels.getString("newline.message") + "\n" + 344 " " + StringHelper.postpad(helpFlags[19] ,maxLength, ' ') + labels.getString("nonewline.message") + "\n" 345 ); 346 System.exit(0); 347 } break; 348 case 2:{ 349 System.out.println(MessageFormat.format(labels.getString("version"), (Object [])new String [] {version})); 351 System.exit(0); 352 } break; 353 case 3:{ 354 System.out.println( 355 labels.getString("base64") + " -- " + labels.getString("purpose.message") + "\n" + 356 MessageFormat.format(labels.getString("copyright"), (Object [])new String [] {"2001-2002", "Stephen Ostermiller (http://ostermiller.org/contact.pl?regarding=Java+Utilities)"}) + "\n\n" + 357 labels.getString("license") 358 ); 359 System.exit(0); 360 } break; 361 case 'd':{ 362 action = ACTION_DECODE; 363 } break; 364 case 'a':{ 365 forceDecode = true; 366 } break; 367 case 5:{ 368 forceDecode = false; 369 } break; 370 case 'e':{ 371 action = ACTION_ENCODE; 372 } break; 373 case 'l':{ 374 lineBreaks = true; 375 } break; 376 case 6:{ 377 lineBreaks = false; 378 } break; 379 case 'g':{ 380 action = ACTION_GUESS; 381 } break; 382 case 'x':{ 383 extension = opts.getOptarg(); 384 if (extension == null) extension = ""; 385 } break; 386 case 'f':{ 387 force = true; 388 } break; 389 case 4:{ 390 force = false; 391 } break; 392 case 'v':{ 393 printMessages = true; 394 printErrors = true; 395 } break; 396 case 'q':{ 397 printMessages = false; 398 printErrors = true; 399 } break; 400 case 'Q':{ 401 printMessages = false; 402 printErrors = false; 403 } break; 404 case 7: { 405 argumentType = ARGUMENT_FILE; 406 } break; 407 case 8: { 408 argumentType = ARGUMENT_STRING; 409 } break; 410 case 'n': { 411 decodeEndLine = true; 412 } break; 413 case 9: { 414 decodeEndLine = false; 415 } break; 416 default:{ 417 System.err.println(labels.getString("unknownarg")); 418 System.exit(1); 419 } 420 } 421 } 422 423 int exitCond = 0; 424 boolean done = false; 425 for (int i=opts.getOptind(); i<args.length; i++){ 426 done = true; 427 File source = new File(args[i]); 428 if (argumentType == ARGUMENT_STRING || (argumentType == ARGUMENT_GUESS && !source.exists())){ 429 try { 430 int fileAction = action; 431 if (fileAction == ACTION_GUESS){ 432 if (isBase64(args[i])){ 433 fileAction = ACTION_DECODE; 434 } else { 435 fileAction = ACTION_ENCODE; 436 } 437 } 438 if (fileAction == ACTION_ENCODE){ 439 if (printMessages){ 440 System.out.println(labels.getString("encodingarg")); 441 } 442 encode(new ByteArrayInputStream(args[i].getBytes()), System.out, lineBreaks); 443 } else { 444 if (printMessages){ 445 System.out.println(labels.getString("decodingarg")); 446 } 447 decode(new ByteArrayInputStream(args[i].getBytes()), System.out, !forceDecode); 448 if (decodeEndLine) System.out.println(); 449 } 450 } catch (Base64DecodingException x){ 451 if(printErrors){ 452 System.err.println(args[i] + ": " + x.getMessage() + " " + labels.getString("unexpectedcharforce")); 453 } 454 exitCond = 1; 455 } catch (IOException x){ 456 if(printErrors){ 457 System.err.println(args[i] + ": " + x.getMessage()); 458 } 459 exitCond = 1; 460 } 461 } else if (!source.exists()){ 462 if(printErrors){ 463 System.err.println(MessageFormat.format(labels.getString("doesnotexist"), (Object [])new String [] {args[i]})); 464 } 465 exitCond = 1; 466 } else if (!source.canRead()){ 467 if(printErrors){ 468 System.err.println(MessageFormat.format(labels.getString("cantread"), (Object [])new String [] {args[i]})); 469 } 470 exitCond = 1; 471 } else { 472 try { 473 int fileAction = action; 474 if (fileAction == ACTION_GUESS){ 475 if (isBase64(source)){ 476 fileAction = ACTION_DECODE; 477 } else { 478 fileAction = ACTION_ENCODE; 479 } 480 } 481 String outName = args[i]; 482 if (extension.length() > 0){ 483 if (fileAction == ACTION_ENCODE){ 484 outName = args[i] + "." + extension; 485 } else { 486 if (args[i].endsWith("." + extension)){ 487 outName = args[i].substring(0, args[i].length() - (extension.length() + 1)); 488 } 489 } 490 } 491 File outFile = new File(outName); 492 if (!force && outFile.exists()){ 493 if(printErrors){ 494 System.err.println(MessageFormat.format(labels.getString("overwrite"), (Object [])new String [] {outName})); 495 } 496 exitCond = 1; 497 } else if (!(outFile.exists() || outFile.createNewFile()) || !outFile.canWrite()){ 498 if(printErrors){ 499 System.err.println(MessageFormat.format(labels.getString("cantwrite"), (Object [])new String [] {outName})); 500 } 501 exitCond = 1; 502 } else { 503 if (fileAction == ACTION_ENCODE){ 504 if (printMessages){ 505 System.out.println(MessageFormat.format(labels.getString("encoding"), (Object [])new String [] {args[i], outName})); 506 } 507 encode(source, outFile, lineBreaks); 508 } else { 509 if (printMessages){ 510 System.out.println(MessageFormat.format(labels.getString("decoding"), (Object [])new String [] {args[i], outName})); 511 } 512 decode(source, outFile, !forceDecode); 513 } 514 } 515 } catch (Base64DecodingException x){ 516 if(printErrors){ 517 System.err.println(args[i] + ": " + x.getMessage() + " " + labels.getString("unexpectedcharforce")); 518 } 519 exitCond = 1; 520 } catch (IOException x){ 521 if(printErrors){ 522 System.err.println(args[i] + ": " + x.getMessage()); 523 } 524 exitCond = 1; 525 } 526 } 527 } 528 if (!done){ 529 try { 530 if (action == ACTION_GUESS){ 531 if(printErrors){ 532 System.err.println(labels.getString("cantguess")); 533 } 534 exitCond = 1; 535 } else if (action == ACTION_ENCODE){ 536 encode( 537 new BufferedInputStream(System.in), 538 new BufferedOutputStream(System.out), 539 lineBreaks 540 ); 541 } else { 542 decode( 543 new BufferedInputStream(System.in), 544 new BufferedOutputStream(System.out), 545 !forceDecode 546 ); 547 if (decodeEndLine) System.out.println(); 548 } 549 } catch (Base64DecodingException x){ 550 if(printErrors){ 551 System.err.println(x.getMessage() + " " + labels.getString("unexpectedcharforce")); 552 } 553 exitCond = 1; 554 } catch (IOException x){ 555 if(printErrors){ 556 System.err.println(x.getMessage()); 557 } 558 exitCond = 1; 559 } 560 } 561 System.exit(exitCond); 562 } 563 564 575 public static String encode(String string){ 576 return new String (encode(string.getBytes())); 577 } 578 579 590 public static String encode(String string, String enc) throws UnsupportedEncodingException { 591 return new String (encode(string.getBytes(enc)), enc); 592 } 593 594 603 public static String encodeToString(byte[] bytes){ 604 return encodeToString(bytes, false); 605 } 606 607 616 public static String encodeToString(byte[] bytes, boolean lineBreaks){ 617 try { 618 return new String (encode(bytes, lineBreaks), "ASCII"); 619 } catch (UnsupportedEncodingException iex){ 620 throw new RuntimeException (iex); 622 } 623 } 624 625 634 public static byte[] encode(byte[] bytes){ 635 return encode(bytes, false); 636 } 637 638 647 public static byte[] encode(byte[] bytes, boolean lineBreaks){ 648 ByteArrayInputStream in = new ByteArrayInputStream(bytes); 649 int mod; 655 int length = bytes.length; 656 if ((mod = length % 3) != 0){ 657 length += 3 - mod; 658 } 659 length = length * 4 / 3; 660 ByteArrayOutputStream out = new ByteArrayOutputStream(length); 661 try { 662 encode(in, out, lineBreaks); 663 } catch (IOException x){ 664 throw new RuntimeException (x); 668 } 669 return out.toByteArray(); 670 } 671 672 680 public static void encode(File fIn) throws IOException { 681 encode(fIn, fIn, true); 682 } 683 684 693 public static void encode(File fIn, boolean lineBreaks) throws IOException { 694 encode(fIn, fIn, lineBreaks); 695 } 696 697 707 public static void encode(File fIn, File fOut) throws IOException { 708 encode(fIn, fOut, true); 709 } 710 711 721 public static void encode(File fIn, File fOut, boolean lineBreaks) throws IOException { 722 File temp = null; 723 InputStream in = null; 724 OutputStream out = null; 725 try { 726 in = new BufferedInputStream(new FileInputStream(fIn)); 727 temp = File.createTempFile("Base64", null, null); 728 out = new BufferedOutputStream(new FileOutputStream(temp)); 729 encode(in, out, lineBreaks); 730 in.close(); 731 in = null; 732 out.flush(); 733 out.close(); 734 out = null; 735 FileHelper.move(temp, fOut, true); 736 } finally { 737 if (in != null){ 738 in.close(); 739 in = null; 740 } 741 if (out != null){ 742 out.flush(); 743 out.close(); 744 out = null; 745 } 746 } 747 } 748 749 759 public static void encode(InputStream in, OutputStream out) throws IOException { 760 encode(in, out, true); 761 } 762 763 773 public static void encode(InputStream in, OutputStream out, boolean lineBreaks) throws IOException { 774 int[] inBuffer = new int[3]; 777 int lineCount = 0; 778 779 boolean done = false; 780 while (!done && (inBuffer[0] = in.read()) != END_OF_INPUT){ 781 inBuffer[1] = in.read(); 783 inBuffer[2] = in.read(); 784 785 796 out.write(base64Chars[ inBuffer[0] >> 2 ]); 798 if (inBuffer[1] != END_OF_INPUT){ 799 out.write(base64Chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]); 801 if (inBuffer[2] != END_OF_INPUT){ 802 out.write(base64Chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]); 804 out.write(base64Chars [inBuffer[2] & 0x3F]); 806 } else { 807 out.write(base64Chars [((inBuffer[1] << 2) & 0x3c)]); 809 out.write('='); 811 done = true; 812 } 813 } else { 814 out.write(base64Chars [(( inBuffer[0] << 4 ) & 0x30)]); 816 out.write('='); 818 out.write('='); 819 done = true; 820 } 821 lineCount += 4; 822 if (lineBreaks && lineCount >= 76){ 823 out.write('\n'); 824 lineCount = 0; 825 } 826 } 827 if (lineBreaks && lineCount >= 1){ 828 out.write('\n'); 829 lineCount = 0; 830 } 831 out.flush(); 832 } 833 834 846 public static String decode(String string){ 847 return new String (decode(string.getBytes())); 848 } 849 850 862 public static String decode(String string, String enc) throws UnsupportedEncodingException { 863 return new String (decode(string.getBytes(enc)), enc); 864 } 865 866 879 public static String decode(String string, String encIn, String encOut) throws UnsupportedEncodingException { 880 return new String (decode(string.getBytes(encIn)), encOut); 881 } 882 883 895 public static String decodeToString(String string){ 896 return new String (decode(string.getBytes())); 897 } 898 899 911 public static String decodeToString(String string, String enc) throws UnsupportedEncodingException { 912 return new String (decode(string.getBytes(enc)), enc); 913 } 914 915 928 public static String decodeToString(String string, String encIn, String encOut) throws UnsupportedEncodingException { 929 return new String (decode(string.getBytes(encIn)), encOut); 930 } 931 932 945 public static void decodeToStream(String string, OutputStream out) throws IOException { 946 decode(new ByteArrayInputStream(string.getBytes()), out); 947 } 948 949 962 public static void decodeToStream(String string, String enc, OutputStream out) throws UnsupportedEncodingException, IOException { 963 decode(new ByteArrayInputStream(string.getBytes(enc)), out); 964 } 965 966 978 public static byte[] decodeToBytes(String string){ 979 return decode(string.getBytes()); 980 } 981 982 994 public static byte[] decodeToBytes(String string, String enc) throws UnsupportedEncodingException { 995 return decode(string.getBytes(enc)); 996 } 997 998 1010 public static String decodeToString(byte[] bytes){ 1011 return new String (decode(bytes)); 1012 } 1013 1014 1026 public static String decodeToString(byte[] bytes, String enc) throws UnsupportedEncodingException { 1027 return new String (decode(bytes), enc); 1028 } 1029 1030 1040 public static byte[] decodeToBytes(byte[] bytes){ 1041 return decode(bytes); 1042 } 1043 1044 1054 public static byte[] decode(byte[] bytes){ 1055 ByteArrayInputStream in = new ByteArrayInputStream(bytes); 1056 int mod; 1062 int length = bytes.length; 1063 if ((mod = length % 4) != 0){ 1064 length += 4 - mod; 1065 } 1066 length = length * 3 / 4; 1067 ByteArrayOutputStream out = new ByteArrayOutputStream(length); 1068 try { 1069 decode(in, out, false); 1070 } catch (IOException x){ 1071 throw new RuntimeException (x); 1075 } 1076 return out.toByteArray(); 1077 } 1078 1079 1090 public static void decode(byte[] bytes, OutputStream out) throws IOException { 1091 ByteArrayInputStream in = new ByteArrayInputStream(bytes); 1092 decode(in, out, false); 1093 } 1094 1095 1106 public static void decodeToStream(byte[] bytes, OutputStream out) throws IOException { 1107 ByteArrayInputStream in = new ByteArrayInputStream(bytes); 1108 decode(in, out, false); 1109 } 1110 1111 1123 public static void decode(File fIn) throws IOException { 1124 decode(fIn, fIn, true); 1125 } 1126 1127 1140 public static void decode(File fIn, boolean throwExceptions) throws IOException { 1141 decode(fIn, fIn, throwExceptions); 1142 } 1143 1144 1157 public static void decode(File fIn, File fOut) throws IOException { 1158 decode(fIn, fOut, true); 1159 } 1160 1161 1175 public static void decode(File fIn, File fOut, boolean throwExceptions) throws IOException { 1176 File temp = null; 1177 InputStream in = null; 1178 OutputStream out = null; 1179 try { 1180 in = new BufferedInputStream(new FileInputStream(fIn)); 1181 temp = File.createTempFile("Base64", null, null); 1182 out = new BufferedOutputStream(new FileOutputStream(temp)); 1183 decode(in, out, throwExceptions); 1184 in.close(); 1185 in = null; 1186 out.flush(); 1187 out.close(); 1188 out = null; 1189 FileHelper.move(temp, fOut, true); 1190 } finally { 1191 if (in != null){ 1192 try { 1193 in.close(); 1194 } catch (IOException ignore){ 1195 if (throwExceptions) throw ignore; 1196 } 1197 in = null; 1198 } 1199 if (out != null){ 1200 try { 1201 out.flush(); 1202 out.close(); 1203 } catch (IOException ignore){ 1204 if (throwExceptions) throw ignore; 1205 } 1206 out = null; 1207 } 1208 } 1209 } 1210 1211 1223 private static final int readBase64(InputStream in, boolean throwExceptions) throws IOException { 1224 int read; 1225 int numPadding = 0; 1226 do { 1227 read = in.read(); 1228 if (read == END_OF_INPUT) return END_OF_INPUT; 1229 read = reverseBase64Chars[(byte)read]; 1230 if (throwExceptions && (read == NON_BASE_64 || (numPadding > 0 && read > NON_BASE_64))){ 1231 throw new Base64DecodingException ( 1232 MessageFormat.format( 1233 labels.getString("unexpectedchar"), 1234 (Object [])new String [] { 1235 "'" + (char)read + "' (0x" + Integer.toHexString(read) + ")" 1236 } 1237 ), 1238 (char)read 1239 ); 1240 } 1241 if (read == NON_BASE_64_PADDING){ 1242 numPadding++; 1243 } 1244 } while (read <= NON_BASE_64); 1245 return read; 1246 } 1247 1248 1259 public static byte[] decodeToBytes(InputStream in) throws IOException { 1260 ByteArrayOutputStream out = new ByteArrayOutputStream(); 1261 decode(in, out, false); 1262 return out.toByteArray(); 1263 } 1264 1265 1278 public static String decodeToString(InputStream in) throws IOException { 1279 return new String (decodeToBytes(in)); 1280 } 1281 1282 1295 public static String decodeToString(InputStream in, String enc) throws IOException { 1296 return new String (decodeToBytes(in), enc); 1297 } 1298 1299 1312 public static void decode(InputStream in, OutputStream out) throws IOException { 1313 decode(in, out, true); 1314 } 1315 1316 1330 public static void decode(InputStream in, OutputStream out, boolean throwExceptions) throws IOException { 1331 int[] inBuffer = new int[4]; 1333 1334 boolean done = false; 1337 while (!done && (inBuffer[0] = readBase64(in, throwExceptions)) != END_OF_INPUT 1338 && (inBuffer[1] = readBase64(in, throwExceptions)) != END_OF_INPUT){ 1339 inBuffer[2] = readBase64(in, throwExceptions); 1341 inBuffer[3] = readBase64(in, throwExceptions); 1342 1343 1353 out.write(inBuffer[0] << 2 | inBuffer[1] >> 4); 1355 if (inBuffer[2] != END_OF_INPUT){ 1356 out.write(inBuffer[1] << 4 | inBuffer[2] >> 2); 1358 if (inBuffer[3] != END_OF_INPUT){ 1359 out.write(inBuffer[2] << 6 | inBuffer[3]); 1361 } else { 1362 done = true; 1363 } 1364 } else { 1365 done = true; 1366 } 1367 } 1368 out.flush(); 1369 } 1370 1371 1393 public static boolean isBase64(byte[] bytes){ 1394 try { 1395 return isBase64(new ByteArrayInputStream(bytes)); 1396 } catch (IOException x){ 1397 return false; 1401 } 1402 } 1403 1404 1429 public static boolean isBase64(String string){ 1430 return isBase64(string.getBytes()); 1431 } 1432 1433 1456 public static boolean isBase64(String string, String enc) throws UnsupportedEncodingException { 1457 return isBase64(string.getBytes(enc)); 1458 } 1459 1460 1484 public static boolean isBase64(File fIn) throws IOException { 1485 return isBase64(new BufferedInputStream(new FileInputStream(fIn))); 1486 } 1487 1488 1513 public static boolean isBase64(InputStream in) throws IOException { 1514 long numBase64Chars = 0; 1515 int numPadding = 0; 1516 int read; 1517 1518 while ((read = in.read()) != -1){ 1519 read = reverseBase64Chars[read]; 1520 if (read == NON_BASE_64){ 1521 return false; 1522 } else if (read == NON_BASE_64_WHITESPACE){ 1523 } else if (read == NON_BASE_64_PADDING){ 1524 numPadding++; 1525 numBase64Chars++; 1526 } else if (numPadding > 0){ 1527 return false; 1528 } else { 1529 numBase64Chars++; 1530 } 1531 } 1532 if (numBase64Chars == 0) return false; 1533 if (numBase64Chars % 4 != 0) return false; 1534 return true; 1535 } 1536} 1537 | Popular Tags |