1 package org.enhydra.barracuda.plankton.data; 2 3 77 78 94 public class Base64 { 95 static private final int BASELENGTH = 255; 96 static private final int LOOKUPLENGTH = 64; 97 static private final int TWENTYFOURBITGROUP = 24; 98 static private final int EIGHTBIT = 8; 99 static private final int SIXTEENBIT = 16; 100 static private final int SIXBIT = 6; 101 static private final int FOURBYTE = 4; 102 static private final int SIGN = -128; 103 static private final byte PAD = (byte) '='; 104 static private final boolean fDebug = false; 105 static private byte [] base64Alphabet = new byte[BASELENGTH]; 106 static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; 107 108 109 static { 110 111 for (int i = 0; i<BASELENGTH; i++) { 112 base64Alphabet[i] = -1; 113 } 114 for (int i = 'Z'; i >= 'A'; i--) { 115 base64Alphabet[i] = (byte) (i-'A'); 116 } 117 for (int i = 'z'; i>= 'a'; i--) { 118 base64Alphabet[i] = (byte) (i-'a' + 26); 119 } 120 121 for (int i = '9'; i >= '0'; i--) { 122 base64Alphabet[i] = (byte) (i-'0' + 52); 123 } 124 125 base64Alphabet['+'] = 62; 126 base64Alphabet['/'] = 63; 127 128 for (int i = 0; i<=25; i++) 129 lookUpBase64Alphabet[i] = (byte) ('A'+i); 130 131 for (int i = 26, j = 0; i<=51; i++, j++) 132 lookUpBase64Alphabet[i] = (byte) ('a'+ j); 133 134 for (int i = 52, j = 0; i<=61; i++, j++) 135 lookUpBase64Alphabet[i] = (byte) ('0' + j); 136 lookUpBase64Alphabet[62] = (byte) '+'; 137 lookUpBase64Alphabet[63] = (byte) '/'; 138 139 } 140 141 protected static boolean isWhiteSpace (byte octect) { 142 return(octect==0x20 || octect==0xd || octect==0xa || octect==0x9); 143 } 144 145 protected static boolean isPad (byte octect) { 146 return(octect==PAD); 147 } 148 149 protected static boolean isData (byte octect) { 150 return(base64Alphabet[octect]!=-1); 151 } 152 153 public static boolean isBase64(String isValidString) { 154 if (isValidString==null) 155 return false; 156 return(isArrayByteBase64(isValidString.getBytes())); 157 } 158 159 160 public static boolean isBase64(byte octect) { 161 return(isWhiteSpace(octect) || isPad(octect) || isData(octect)); 162 } 163 164 165 175 public static synchronized byte[] removeWhiteSpace(byte[] data) { 176 if (data==null) 177 return null; 178 179 int newSize = 0; 180 int len = data.length; 181 int i =0; 182 for (; i<len; i++) { 183 if (!isWhiteSpace(data[i])) 184 newSize++; 185 } 186 187 if (newSize==len) 188 return data; 190 191 byte[] arrayWithoutSpaces = new byte[newSize]; 193 int j = 0; 194 for (i=0;i<len;i++) { 195 if (isWhiteSpace(data[i])) 196 continue; 197 else 198 arrayWithoutSpaces[j++] = data[i]; } 200 return arrayWithoutSpaces; 201 202 } 203 204 public static synchronized boolean isArrayByteBase64(byte[] arrayOctect) { 205 return(getDecodedDataLength(arrayOctect) >= 0); 206 } 207 208 214 public static synchronized byte[] encode(byte[] binaryData) { 215 if (binaryData==null) 216 return null; 217 218 int lengthDataBits = binaryData.length*EIGHTBIT; 219 int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; 220 int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; 221 byte encodedData[] = null; 222 223 224 if (fewerThan24bits!=0) encodedData = new byte[ (numberTriplets + 1)*4 ]; 226 else encodedData = new byte[ numberTriplets*4 ]; 228 229 byte k=0, l=0, b1=0,b2=0,b3=0; 230 231 int encodedIndex = 0; 232 int dataIndex = 0; 233 int i = 0; 234 if (fDebug) { 235 System.out.println("number of triplets = " + numberTriplets); 236 } 237 for (i = 0; i<numberTriplets; i++) { 238 239 dataIndex = i*3; 240 b1 = binaryData[dataIndex]; 241 b2 = binaryData[dataIndex + 1]; 242 b3 = binaryData[dataIndex + 2]; 243 244 if (fDebug) { 245 System.out.println("b1= " + b1 +", b2= " + b2 + ", b3= " + b3); 246 } 247 248 l = (byte)(b2 & 0x0f); 249 k = (byte)(b1 & 0x03); 250 251 encodedIndex = i*4; 252 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 253 254 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 255 byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); 256 257 encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; 258 if (fDebug) { 259 System.out.println("val2 = " + val2); 260 System.out.println("k4 = " + (k<<4)); 261 System.out.println("vak = " + (val2 | (k<<4))); 262 } 263 264 encodedData[encodedIndex+1] = lookUpBase64Alphabet[ val2 | (k<<4)]; 265 encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2) | val3 ]; 266 encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ]; 267 } 268 269 dataIndex = i*3; 271 encodedIndex = i*4; 272 if (fewerThan24bits==EIGHTBIT) { 273 b1 = binaryData[dataIndex]; 274 k = (byte) (b1 &0x03); 275 if (fDebug) { 276 System.out.println("b1=" + b1); 277 System.out.println("b1<<2 = " + (b1>>2)); 278 } 279 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 280 encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; 281 encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ]; 282 encodedData[encodedIndex + 2] = PAD; 283 encodedData[encodedIndex + 3] = PAD; 284 } else if (fewerThan24bits==SIXTEENBIT) { 285 286 b1 = binaryData[dataIndex]; 287 b2 = binaryData[dataIndex +1 ]; 288 l = (byte) (b2 &0x0f); 289 k = (byte) (b1 &0x03); 290 291 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 292 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 293 294 encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; 295 encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ val2 | (k<<4)]; 296 encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ]; 297 encodedData[encodedIndex + 3] = PAD; 298 } 299 return encodedData; 300 } 301 302 308 public static String encode(String stringData) { 309 if (stringData==null) return null; 310 311 byte[] encoded = encode(stringData.getBytes()); 312 313 return (encoded==null) ? null : new String (encoded); 314 } 315 316 322 public static synchronized byte[] decode(byte[] base64Data) { 323 324 if (base64Data==null) 325 return null; 326 327 byte[] normalizedBase64Data = removeWhiteSpace(base64Data); 328 329 if (normalizedBase64Data.length%FOURBYTE!=0) { 330 return null; } 332 333 int numberQuadruple = (normalizedBase64Data.length/FOURBYTE); 334 335 if (numberQuadruple==0) 336 return new byte[0]; 337 338 byte decodedData[] = null; 339 byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0; 340 byte d1=0,d2=0,d3=0,d4=0; 341 342 343 344 int i = 0; 347 int encodedIndex = 0; 348 int dataIndex = 0; 349 decodedData = new byte[ (numberQuadruple)*3]; 350 351 for (; i<numberQuadruple-1; i++) { 352 353 if (!isData((d1 = normalizedBase64Data[dataIndex++]))|| 354 !isData((d2 = normalizedBase64Data[dataIndex++]))|| 355 !isData((d3 = normalizedBase64Data[dataIndex++]))|| 356 !isData((d4 = normalizedBase64Data[dataIndex++]))) 357 return null; 359 b1 = base64Alphabet[d1]; 360 b2 = base64Alphabet[d2]; 361 b3 = base64Alphabet[d3]; 362 b4 = base64Alphabet[d4]; 363 364 decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4) ; 365 decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4) |((b3>>2) & 0xf)); 366 decodedData[encodedIndex++] = (byte)(b3<<6 | b4); 367 } 368 369 370 if (!isData((d1 = normalizedBase64Data[dataIndex++])) || 371 !isData((d2 = normalizedBase64Data[dataIndex++]))) { 372 return null; } 374 375 376 b1 = base64Alphabet[d1]; 377 b2 = base64Alphabet[d2]; 378 379 d3 = normalizedBase64Data[dataIndex++]; 380 d4 = normalizedBase64Data[dataIndex++]; 381 if (!isData((d3)) || 382 !isData((d4))) { if (isPad(d3) && isPad(d4)) { if ((b2 & 0xf)!=0) return null; 386 byte[] tmp = new byte[ i*3 + 1 ]; 387 System.arraycopy(decodedData, 0, tmp, 0, i*3); 388 tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4) ; 389 return tmp; 390 } else if (!isPad(d3) && isPad(d4)) { b3 = base64Alphabet[ d3 ]; 392 if ((b3 & 0x3)!=0) return null; 394 byte[] tmp = new byte[ i*3 + 2 ]; 395 System.arraycopy(decodedData, 0, tmp, 0, i*3); 396 tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4); 397 tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4) |((b3>>2) & 0xf)); 398 return tmp; 399 } else { 400 return null; } 402 } else { b3 = base64Alphabet[ d3 ]; 404 b4 = base64Alphabet[ d4 ]; 405 decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4) ; 406 decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4) |((b3>>2) & 0xf)); 407 decodedData[encodedIndex++] = (byte)(b3<<6 | b4); 408 409 } 410 411 return decodedData; 412 } 413 414 420 public static String decode(String base64Data) { 421 if (base64Data==null) return null; 422 423 byte[] decoded = decode(base64Data.getBytes()); 424 425 return (decoded==null) ? null : new String (decoded); 426 } 427 428 437 static public synchronized int getDecodedDataLength(byte[] base64Data) { 438 439 if (base64Data==null) 440 return -1; 441 442 if (base64Data.length==0) 443 return 0; 444 445 byte[] decodedData = null; 447 448 if ((decodedData = decode(base64Data))==null) return -1; 450 451 return decodedData.length; 452 } 453 } 454 | Popular Tags |