Base64Coder.java (5441B)
1 package org.xmlrpc.android; 2 3 /** 4 * A Base64 Encoder/Decoder. 5 * 6 * <p> 7 * This class is used to encode and decode data in Base64 format as described in 8 * RFC 1521. 9 * 10 * <p> 11 * This is "Open Source" software and released under the <a 12 * href="http://www.gnu.org/licenses/lgpl.html">GNU/LGPL</a> license.<br> 13 * It is provided "as is" without warranty of any kind.<br> 14 * Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br> 15 * Home page: <a href="http://www.source-code.biz">www.source-code.biz</a><br> 16 * 17 * <p> 18 * Version history:<br> 19 * 2003-07-22 Christian d'Heureuse (chdh): Module created.<br> 20 * 2005-08-11 chdh: Lincense changed from GPL to LGPL.<br> 21 * 2006-11-21 chdh:<br> 22 * Method encode(String) renamed to encodeString(String).<br> 23 * Method decode(String) renamed to decodeString(String).<br> 24 * New method encode(byte[],int) added.<br> 25 * New method decode(String) added.<br> 26 */ 27 28 class Base64Coder { 29 30 // Mapping table from 6-bit nibbles to Base64 characters. 31 private static char[] map1 = new char[64]; 32 static { 33 int i = 0; 34 for (char c = 'A'; c <= 'Z'; c++) { 35 map1[i++] = c; 36 } 37 for (char c = 'a'; c <= 'z'; c++) { 38 map1[i++] = c; 39 } 40 for (char c = '0'; c <= '9'; c++) { 41 map1[i++] = c; 42 } 43 map1[i++] = '+'; 44 map1[i++] = '/'; 45 } 46 47 // Mapping table from Base64 characters to 6-bit nibbles. 48 private static byte[] map2 = new byte[128]; 49 static { 50 for (int i = 0; i < map2.length; i++) { 51 map2[i] = -1; 52 } 53 for (int i = 0; i < 64; i++) { 54 map2[map1[i]] = (byte) i; 55 } 56 } 57 58 /** 59 * Encodes a string into Base64 format. No blanks or line breaks are 60 * inserted. 61 * 62 * @param s 63 * a String to be encoded. 64 * @return A String with the Base64 encoded data. 65 */ 66 static String encodeString(String s) { 67 return new String(encode(s.getBytes())); 68 } 69 70 /** 71 * Encodes a byte array into Base64 format. No blanks or line breaks are 72 * inserted. 73 * 74 * @param in 75 * an array containing the data bytes to be encoded. 76 * @return A character array with the Base64 encoded data. 77 */ 78 static char[] encode(byte[] in) { 79 return encode(in, in.length); 80 } 81 82 /** 83 * Encodes a byte array into Base64 format. No blanks or line breaks are 84 * inserted. 85 * 86 * @param in 87 * an array containing the data bytes to be encoded. 88 * @param iLen 89 * number of bytes to process in <code>in</code>. 90 * @return A character array with the Base64 encoded data. 91 */ 92 static char[] encode(byte[] in, int iLen) { 93 int oDataLen = (iLen * 4 + 2) / 3; // output length without padding 94 int oLen = ((iLen + 2) / 3) * 4; // output length including padding 95 char[] out = new char[oLen]; 96 int ip = 0; 97 int op = 0; 98 while (ip < iLen) { 99 int i0 = in[ip++] & 0xff; 100 int i1 = ip < iLen ? in[ip++] & 0xff : 0; 101 int i2 = ip < iLen ? in[ip++] & 0xff : 0; 102 int o0 = i0 >>> 2; 103 int o1 = ((i0 & 3) << 4) | (i1 >>> 4); 104 int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); 105 int o3 = i2 & 0x3F; 106 out[op++] = map1[o0]; 107 out[op++] = map1[o1]; 108 out[op] = op < oDataLen ? map1[o2] : '='; 109 op++; 110 out[op] = op < oDataLen ? map1[o3] : '='; 111 op++; 112 } 113 return out; 114 } 115 116 /** 117 * Decodes a string from Base64 format. 118 * 119 * @param s 120 * a Base64 String to be decoded. 121 * @return A String containing the decoded data. 122 * @throws IllegalArgumentException 123 * if the input is not valid Base64 encoded data. 124 */ 125 static String decodeString(String s) { 126 return new String(decode(s)); 127 } 128 129 /** 130 * Decodes a byte array from Base64 format. 131 * 132 * @param s 133 * a Base64 String to be decoded. 134 * @return An array containing the decoded data bytes. 135 * @throws IllegalArgumentException 136 * if the input is not valid Base64 encoded data. 137 */ 138 static byte[] decode(String s) { 139 return decode(s.toCharArray()); 140 } 141 142 /** 143 * Decodes a byte array from Base64 format. No blanks or line breaks are 144 * allowed within the Base64 encoded data. 145 * 146 * @param in 147 * a character array containing the Base64 encoded data. 148 * @return An array containing the decoded data bytes. 149 * @throws IllegalArgumentException 150 * if the input is not valid Base64 encoded data. 151 */ 152 static byte[] decode(char[] in) { 153 int iLen = in.length; 154 if (iLen % 4 != 0) { 155 throw new IllegalArgumentException( 156 "Length of Base64 encoded input string is not a multiple of 4."); 157 } 158 while (iLen > 0 && in[iLen - 1] == '=') { 159 iLen--; 160 } 161 int oLen = (iLen * 3) / 4; 162 byte[] out = new byte[oLen]; 163 int ip = 0; 164 int op = 0; 165 while (ip < iLen) { 166 int i0 = in[ip++]; 167 int i1 = in[ip++]; 168 int i2 = ip < iLen ? in[ip++] : 'A'; 169 int i3 = ip < iLen ? in[ip++] : 'A'; 170 if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) { 171 throw new IllegalArgumentException( 172 "Illegal character in Base64 encoded data."); 173 } 174 int b0 = map2[i0]; 175 int b1 = map2[i1]; 176 int b2 = map2[i2]; 177 int b3 = map2[i3]; 178 if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) { 179 throw new IllegalArgumentException( 180 "Illegal character in Base64 encoded data."); 181 } 182 int o0 = (b0 << 2) | (b1 >>> 4); 183 int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2); 184 int o2 = ((b2 & 3) << 6) | b3; 185 out[op++] = (byte) o0; 186 if (op < oLen) { 187 out[op++] = (byte) o1; 188 } 189 if (op < oLen) { 190 out[op++] = (byte) o2; 191 } 192 } 193 return out; 194 } 195 196 // Dummy constructor. 197 private Base64Coder() { 198 } 199 }