1 31 32 package org.apache.commons.httpclient.util; 33 34 import org.apache.commons.httpclient.HttpConstants; 35 36 52 public final class Base64 { 53 54 55 private static final int BASELENGTH = 255; 56 57 58 private static final int LOOKUPLENGTH = 64; 59 60 61 private static final int TWENTYFOURBITGROUP = 24; 62 63 64 private static final int EIGHTBIT = 8; 65 66 67 private static final int SIXTEENBIT = 16; 68 69 70 private static final int SIXBIT = 6; 71 72 73 private static final int FOURBYTE = 4; 74 75 76 private static final int SIGN = -128; 77 78 79 private static final byte PAD = (byte) '='; 80 81 82 private static final byte [] BASE64_ALPHABET = new byte[BASELENGTH]; 83 84 85 private static final byte [] LOOKUP_BASE64_ALPHABET = new byte[LOOKUPLENGTH]; 86 87 static { 88 89 for (int i = 0; i < BASELENGTH; i++) { 90 BASE64_ALPHABET[i] = -1; 91 } 92 for (int i = 'Z'; i >= 'A'; i--) { 93 BASE64_ALPHABET[i] = (byte) (i - 'A'); 94 } 95 for (int i = 'z'; i >= 'a'; i--) { 96 BASE64_ALPHABET[i] = (byte) (i - 'a' + 26); 97 } 98 99 for (int i = '9'; i >= '0'; i--) { 100 BASE64_ALPHABET[i] = (byte) (i - '0' + 52); 101 } 102 103 BASE64_ALPHABET['+'] = 62; 104 BASE64_ALPHABET['/'] = 63; 105 106 for (int i = 0; i <= 25; i++) { 107 LOOKUP_BASE64_ALPHABET[i] = (byte) ('A' + i); 108 } 109 110 for (int i = 26, j = 0; i <= 51; i++, j++) { 111 LOOKUP_BASE64_ALPHABET[i] = (byte) ('a' + j); 112 } 113 114 for (int i = 52, j = 0; i <= 61; i++, j++) { 115 LOOKUP_BASE64_ALPHABET[i] = (byte) ('0' + j); 116 } 117 LOOKUP_BASE64_ALPHABET[62] = (byte) '+'; 118 LOOKUP_BASE64_ALPHABET[63] = (byte) '/'; 119 120 } 121 122 125 private Base64() { 126 } 128 129 134 public static boolean isBase64(String isValidString) { 135 return isArrayByteBase64(HttpConstants.getAsciiBytes(isValidString)); 136 } 137 138 139 144 static boolean isBase64(byte octect) { 145 return (octect == PAD || BASE64_ALPHABET[octect] != -1); 147 } 148 149 154 public static boolean isArrayByteBase64(byte[] arrayOctect) { 155 int length = arrayOctect.length; 156 if (length == 0) { 157 return true; 158 } 159 for (int i = 0; i < length; i++) { 160 if (!Base64.isBase64(arrayOctect[i])) { 161 return false; 162 } 163 } 164 return true; 165 } 166 167 173 public static byte[] encode(byte[] binaryData) { 174 175 int lengthDataBits = binaryData.length * EIGHTBIT; 176 int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; 177 int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; 178 byte encodedData[] = null; 179 180 181 if (fewerThan24bits != 0) { encodedData = new byte[(numberTriplets + 1) * 4]; 183 } else { encodedData = new byte[numberTriplets * 4]; 185 } 186 187 byte k = 0; 188 byte l = 0; 189 byte b1 = 0; 190 byte b2 = 0; 191 byte b3 = 0; 192 int encodedIndex = 0; 193 int dataIndex = 0; 194 int i = 0; 195 for (i = 0; i < numberTriplets; i++) { 196 197 dataIndex = i * 3; 198 b1 = binaryData[dataIndex]; 199 b2 = binaryData[dataIndex + 1]; 200 b3 = binaryData[dataIndex + 2]; 201 202 l = (byte) (b2 & 0x0f); 203 k = (byte) (b1 & 0x03); 204 205 encodedIndex = i * 4; 206 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) 207 : (byte) ((b1) >> 2 ^ 0xc0); 208 209 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) 210 : (byte) ((b2) >> 4 ^ 0xf0); 211 byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) 212 : (byte) ((b3) >> 6 ^ 0xfc); 213 214 encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; 215 encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2 216 | (k << 4)]; 217 encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[(l << 2) 218 | val3]; 219 encodedData[encodedIndex + 3] = LOOKUP_BASE64_ALPHABET[b3 & 0x3f]; 220 } 221 222 dataIndex = i * 3; 224 encodedIndex = i * 4; 225 if (fewerThan24bits == EIGHTBIT) { 226 b1 = binaryData[dataIndex]; 227 k = (byte) (b1 & 0x03); 228 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) 229 : (byte) ((b1) >> 2 ^ 0xc0); 230 encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; 231 encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[k << 4]; 232 encodedData[encodedIndex + 2] = PAD; 233 encodedData[encodedIndex + 3] = PAD; 234 } else if (fewerThan24bits == SIXTEENBIT) { 235 b1 = binaryData[dataIndex]; 236 b2 = binaryData[dataIndex + 1]; 237 l = (byte) (b2 & 0x0f); 238 k = (byte) (b1 & 0x03); 239 240 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) 241 : (byte) ((b1) >> 2 ^ 0xc0); 242 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) 243 : (byte) ((b2) >> 4 ^ 0xf0); 244 245 encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; 246 encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2 247 | (k << 4)]; 248 encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[l << 2]; 249 encodedData[encodedIndex + 3] = PAD; 250 } 251 return encodedData; 252 } 253 254 255 261 public static byte[] decode(byte[] base64Data) { 262 264 if (base64Data.length == 0) { 266 return new byte[0]; 267 } 268 269 int numberQuadruple = base64Data.length / FOURBYTE; 270 byte decodedData[] = null; 271 byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; 272 273 int encodedIndex = 0; 274 int dataIndex = 0; 275 { 276 int lastData = base64Data.length; 278 while (base64Data[lastData - 1] == PAD) { 280 if (--lastData == 0) { return new byte[0]; } 281 } 282 decodedData = new byte[lastData - numberQuadruple]; 283 } 284 285 for (int i = 0; i < numberQuadruple; i++) { 286 dataIndex = i * 4; 287 marker0 = base64Data[dataIndex + 2]; 288 marker1 = base64Data[dataIndex + 3]; 289 290 b1 = BASE64_ALPHABET[base64Data[dataIndex]]; 291 b2 = BASE64_ALPHABET[base64Data[dataIndex + 1]]; 292 293 if (marker0 != PAD && marker1 != PAD) { b3 = BASE64_ALPHABET[marker0]; 295 b4 = BASE64_ALPHABET[marker1]; 296 297 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); 298 decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) 299 | ((b3 >> 2) & 0xf)); 300 decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); 301 } else if (marker0 == PAD) { decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4) ; 303 } else if (marker1 == PAD) { b3 = BASE64_ALPHABET[marker0]; 305 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); 306 decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) 307 | ((b3 >> 2) & 0xf)); 308 } 309 encodedIndex += 3; 310 } 311 return decodedData; 312 } 313 } 314 | Popular Tags |