1 // Copyright (c) 1999-2004 Brian Wellington (bwelling (at) xbill.org) 2 3 package org.xbill.DNS.utils; 4 5 import java.io.*; 6 7 /** 8 * Routines for converting between Strings of base64-encoded data and arrays of 9 * binary data. 10 * 11 * @author Brian Wellington 12 */ 13 14 public class base64 { 15 16 private static final String Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 17 18 private 19 base64() {} 20 21 /** 22 * Convert binary data to a base64-encoded String 23 * @param b An array containing binary data 24 * @return A String containing the encoded data 25 */ 26 public static String 27 toString(byte [] b) { 28 ByteArrayOutputStream os = new ByteArrayOutputStream(); 29 30 for (int i = 0; i < (b.length + 2) / 3; i++) { 31 short [] s = new short[3]; 32 short [] t = new short[4]; 33 for (int j = 0; j < 3; j++) { 34 if ((i * 3 + j) < b.length) 35 s[j] = (short) (b[i*3+j] & 0xFF); 36 else 37 s[j] = -1; 38 } 39 40 t[0] = (short) (s[0] >> 2); 41 if (s[1] == -1) 42 t[1] = (short) (((s[0] & 0x3) << 4)); 43 else 44 t[1] = (short) (((s[0] & 0x3) << 4) + (s[1] >> 4)); 45 if (s[1] == -1) 46 t[2] = t[3] = 64; 47 else if (s[2] == -1) { 48 t[2] = (short) (((s[1] & 0xF) << 2)); 49 t[3] = 64; 50 } 51 else { 52 t[2] = (short) (((s[1] & 0xF) << 2) + (s[2] >> 6)); 53 t[3] = (short) (s[2] & 0x3F); 54 } 55 for (int j = 0; j < 4; j++) 56 os.write(Base64.charAt(t[j])); 57 } 58 return new String(os.toByteArray()); 59 } 60 61 /** 62 * Formats data into a nicely formatted base64 encoded String 63 * @param b An array containing binary data 64 * @param lineLength The number of characters per line 65 * @param prefix A string prefixing the characters on each line 66 * @param addClose Whether to add a close parenthesis or not 67 * @return A String representing the formatted output 68 */ 69 public static String 70 formatString(byte [] b, int lineLength, String prefix, boolean addClose) { 71 String s = toString(b); 72 StringBuffer sb = new StringBuffer(); 73 for (int i = 0; i < s.length(); i += lineLength) { 74 sb.append (prefix); 75 if (i + lineLength >= s.length()) { 76 sb.append(s.substring(i)); 77 if (addClose) 78 sb.append(" )"); 79 } 80 else { 81 sb.append(s.substring(i, i + lineLength)); 82 sb.append("\n"); 83 } 84 } 85 return sb.toString(); 86 } 87 88 89 /** 90 * Convert a base64-encoded String to binary data 91 * @param str A String containing the encoded data 92 * @return An array containing the binary data, or null if the string is invalid 93 */ 94 public static byte [] 95 fromString(String str) { 96 ByteArrayOutputStream bs = new ByteArrayOutputStream(); 97 byte [] raw = str.getBytes(); 98 for (int i = 0; i < raw.length; i++) { 99 if (!Character.isWhitespace((char)raw[i])) 100 bs.write(raw[i]); 101 } 102 byte [] in = bs.toByteArray(); 103 if (in.length % 4 != 0) { 104 return null; 105 } 106 107 bs.reset(); 108 DataOutputStream ds = new DataOutputStream(bs); 109 110 for (int i = 0; i < (in.length + 3) / 4; i++) { 111 short [] s = new short[4]; 112 short [] t = new short[3]; 113 114 for (int j = 0; j < 4; j++) 115 s[j] = (short) Base64.indexOf(in[i*4+j]); 116 117 t[0] = (short) ((s[0] << 2) + (s[1] >> 4)); 118 if (s[2] == 64) { 119 t[1] = t[2] = (short) (-1); 120 if ((s[1] & 0xF) != 0) 121 return null; 122 } 123 else if (s[3] == 64) { 124 t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF); 125 t[2] = (short) (-1); 126 if ((s[2] & 0x3) != 0) 127 return null; 128 } 129 else { 130 t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF); 131 t[2] = (short) (((s[2] << 6) + s[3]) & 0xFF); 132 } 133 134 try { 135 for (int j = 0; j < 3; j++) 136 if (t[j] >= 0) 137 ds.writeByte(t[j]); 138 } 139 catch (IOException e) { 140 } 141 } 142 return bs.toByteArray(); 143 } 144 145 } 146