001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the License. 004 * 005 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 006 * specific language governing permission and limitations under the License. 007 * 008 * When distributing Covered Software, include this CDDL Header Notice in each file and include 009 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 010 * Header, with the fields enclosed by brackets [] replaced by your own identifying 011 * information: "Portions copyright [year] [name of copyright owner]". 012 * 013 * Copyright 2015 ForgeRock AS. 014 */ 015 016 017package org.forgerock.util.encode; 018 019import java.util.Arrays; 020 021/** 022 * A very fast and memory efficient class to encode and decode to and from 023 * BASE64 in full accordance with RFC 2045.<br> 024 * <br> 025 * On Windows XP sp1 with 1.4.2_04 and later ;), this encoder and decoder is 026 * about 10 times faster on small arrays (10 - 1000 bytes) and 2-3 times as fast 027 * on larger arrays (10000 - 1000000 bytes) compared to 028 * <code>sun.misc.Encoder()/Decoder()</code>.<br> 029 * <br> 030 * On byte arrays the encoder is about 20% faster than Jakarta Commons Base64 031 * Codec for encode and about 50% faster for decoding large arrays. This 032 * implementation is about twice as fast on very small arrays (< 30 bytes). 033 * If source/destination is a <code>String</code> this version is about three 034 * times as fast due to the fact that the Commons Codec result has to be recoded 035 * to a <code>String</code> from <code>byte[]</code>, which is very expensive.<br> 036 * <br> 037 * This encode/decode algorithm doesn't create any temporary arrays as many 038 * other codecs do, it only allocates the resulting array. This produces less 039 * garbage and it is possible to handle arrays twice as large as algorithms that 040 * create a temporary array. (E.g. Jakarta Commons Codec). It is unknown whether 041 * Sun's <code>sun.misc.Encoder()/Decoder()</code> produce temporary arrays but 042 * since performance is quite low it probably does.<br> 043 * <br> 044 * The encoder produces the same output as the Sun one except that the Sun's 045 * encoder appends a trailing line separator if the last character isn't a pad. 046 * Unclear why but it only adds to the length and is probably a side effect. 047 * Both are in conformance with RFC 2045 though.<br> 048 * Commons codec seem to always att a trailing line separator.<br> 049 * <br> 050 * <b>Note!</b> The encode/decode method pairs (types) come in three versions 051 * with the <b>exact</b> same algorithm and thus a lot of code redundancy. This 052 * is to not create any temporary arrays for transcoding to/from different 053 * format types. The methods not used can simply be commented out.<br> 054 * <br> 055 * There is also a "fast" version of all decode methods that works the same way 056 * as the normal ones, but har a few demands on the decoded input. Normally 057 * though, these fast verions should be used if the source if the input is known 058 * and it hasn't bee tampered with.<br> 059 * <br> 060 * If you find the code useful or you find a bug, please send me a note at 061 * base64 @ miginfocom . com. 062 * 063 * @version 2.2 064 * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 065 */ 066public class Base64 { 067 068 private static final char[] CA = 069 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); 070 private static final int[] IA = new int[256]; 071 072 static { 073 Arrays.fill(IA, -1); 074 for (int i = 0, iS = CA.length; i < iS; i++) { 075 IA[CA[i]] = i; 076 } 077 IA['='] = 0; 078 } 079 080 /** 081 * Decodes a BASE64 encoded byte array. All illegal characters will be 082 * ignored and can handle both arrays with and without line separators. 083 * 084 * @param sArr 085 * The source array. Length 0 will return an empty array. 086 * <code>null</code> will throw an exception. 087 * @return The decoded array of bytes. May be of length 0. Will be 088 * <code>null</code> if the legal characters (including '=') isn't 089 * divideable by 4. (I.e. definitely corrupted). 090 */ 091 public static byte[] decode(final byte[] sArr) { 092 // Check special case 093 final int sLen = sArr.length; 094 095 /* 096 * Count illegal characters (including '\r', '\n') to know what size the 097 * returned array will be, so we don't have to reallocate & copy it 098 * later. 099 */ 100 int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) 101 // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be removed. 102 for (byte aSArr : sArr) { 103 if (IA[aSArr & 0xff] < 0) { 104 sepCnt++; 105 } 106 } 107 108 /* 109 * Check so that legal chars (including '=') are evenly divideable by 4 110 * as specified in RFC 2045. 111 */ 112 if ((sLen - sepCnt) % 4 != 0) { 113 return null; 114 } 115 116 int pad = 0; 117 for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;) { 118 if (sArr[i] == '=') { 119 pad++; 120 } 121 } 122 123 final int len = ((sLen - sepCnt) * 6 >> 3) - pad; 124 125 final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length 126 127 for (int s = 0, d = 0; d < len;) { 128 // Assemble three bytes into an int from four "valid" characters. 129 int i = 0; 130 for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. 131 final int c = IA[sArr[s++] & 0xff]; 132 if (c >= 0) { 133 i |= c << 18 - j * 6; 134 } else { 135 j--; 136 } 137 } 138 139 // Add the bytes 140 dArr[d++] = (byte) (i >> 16); 141 if (d < len) { 142 dArr[d++] = (byte) (i >> 8); 143 if (d < len) { 144 dArr[d++] = (byte) i; 145 } 146 } 147 } 148 149 return dArr; 150 } 151 152 /** 153 * Decodes a BASE64 encoded char array. All illegal characters will be 154 * ignored and can handle both arrays with and without line separators. 155 * 156 * @param sArr 157 * The source array. <code>null</code> or length 0 will return an 158 * empty array. 159 * @return The decoded array of bytes. May be of length 0. Will be 160 * <code>null</code> if the legal characters (including '=') isn't 161 * divideable by 4. (I.e. definitely corrupted). 162 */ 163 public static byte[] decode(final char[] sArr) { 164 // Check special case 165 final int sLen = sArr != null ? sArr.length : 0; 166 if (sLen == 0) { 167 return new byte[0]; 168 } 169 170 /* 171 * Count illegal characters (including '\r', '\n') to know what size the 172 * returned array will be, so we don't have to reallocate & copy it 173 * later. 174 */ 175 int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) 176 for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. 177 { 178 if (IA[sArr[i]] < 0) { 179 sepCnt++; 180 } 181 } 182 183 /* 184 * Check so that legal chars (including '=') are evenly divideable by 4 185 * as specified in RFC 2045. 186 */ 187 if ((sLen - sepCnt) % 4 != 0) { 188 return null; 189 } 190 191 int pad = 0; 192 for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;) { 193 if (sArr[i] == '=') { 194 pad++; 195 } 196 } 197 198 final int len = ((sLen - sepCnt) * 6 >> 3) - pad; 199 200 final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length 201 202 for (int s = 0, d = 0; d < len;) { 203 // Assemble three bytes into an int from four "valid" characters. 204 int i = 0; 205 for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. 206 final int c = IA[sArr[s++]]; 207 if (c >= 0) { 208 i |= c << 18 - j * 6; 209 } else { 210 j--; 211 } 212 } 213 // Add the bytes 214 dArr[d++] = (byte) (i >> 16); 215 if (d < len) { 216 dArr[d++] = (byte) (i >> 8); 217 if (d < len) { 218 dArr[d++] = (byte) i; 219 } 220 } 221 } 222 return dArr; 223 } 224 225 /** 226 * Decodes a BASE64 encoded <code>String</code>. All illegal characters will 227 * be ignored and can handle both strings with and without line separators.<br> 228 * <b>Note!</b> It can be up to about 2x the speed to call 229 * <code>decode(str.toCharArray())</code> instead. That will create a 230 * temporary array though. This version will use <code>str.charAt(i)</code> 231 * to iterate the string. 232 * 233 * @param str 234 * The source string. <code>null</code> or length 0 will return 235 * an empty array. 236 * @return The decoded array of bytes. May be of length 0. Will be 237 * <code>null</code> if the legal characters (including '=') isn't 238 * divideable by 4. (I.e. definitely corrupted). 239 */ 240 public static byte[] decode(final String str) { 241 // Check special case 242 final int sLen = str != null ? str.length() : 0; 243 if (sLen == 0) { 244 return new byte[0]; 245 } 246 247 /* 248 * Count illegal characters (including '\r', '\n') to know what size the 249 * returned array will be, so we don't have to reallocate & copy it 250 * later. 251 */ 252 int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) 253 for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. 254 { 255 if (IA[str.charAt(i)] < 0) { 256 sepCnt++; 257 } 258 } 259 260 /* 261 * Check so that legal chars (including '=') are evenly divideable by 4 262 * as specified in RFC 2045. 263 */ 264 if ((sLen - sepCnt) % 4 != 0) { 265 return null; 266 } 267 268 // Count '=' at end 269 int pad = 0; 270 for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;) { 271 if (str.charAt(i) == '=') { 272 pad++; 273 } 274 } 275 276 final int len = ((sLen - sepCnt) * 6 >> 3) - pad; 277 278 final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length 279 280 for (int s = 0, d = 0; d < len;) { 281 // Assemble three bytes into an int from four "valid" characters. 282 int i = 0; 283 for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. 284 final int c = IA[str.charAt(s++)]; 285 if (c >= 0) { 286 i |= c << 18 - j * 6; 287 } else { 288 j--; 289 } 290 } 291 // Add the bytes 292 dArr[d++] = (byte) (i >> 16); 293 if (d < len) { 294 dArr[d++] = (byte) (i >> 8); 295 if (d < len) { 296 dArr[d++] = (byte) i; 297 } 298 } 299 } 300 return dArr; 301 } 302 303 /** 304 * Decodes a BASE64 encoded byte array that is known to be resonably well 305 * formatted. The method is about twice as fast as {@link #decode(byte[])}. 306 * The preconditions are:<br> 307 * + The array must have a line length of 76 chars OR no line separators at 308 * all (one line).<br> 309 * + Line separator must be "\r\n", as specified in RFC 2045 + The array 310 * must not contain illegal characters within the encoded string<br> 311 * + The array CAN have illegal characters at the beginning and end, those 312 * will be dealt with appropriately.<br> 313 * 314 * @param sArr 315 * The source array. Length 0 will return an empty array. 316 * <code>null</code> will throw an exception. 317 * @return The decoded array of bytes. May be of length 0. 318 */ 319 public static byte[] decodeFast(final byte[] sArr) { 320 // Check special case 321 final int sLen = sArr.length; 322 if (sLen == 0) { 323 return new byte[0]; 324 } 325 326 int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. 327 328 // Trim illegal chars from start 329 while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0) { 330 sIx++; 331 } 332 333 // Trim illegal chars from end 334 while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0) { 335 eIx--; 336 } 337 338 // get the padding count (=) (0, 1 or 2) 339 final int pad = sArr[eIx] == '=' ? sArr[eIx - 1] == '=' ? 2 : 1 : 0; // Count '=' at end. 340 final int cCnt = eIx - sIx + 1; // Content count including possible separators 341 final int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; 342 343 final int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes 344 final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length 345 346 // Decode all but the last 0 - 2 bytes. 347 int d = 0; 348 for (int cc = 0, eLen = len / 3 * 3; d < eLen;) { 349 // Assemble three bytes into an int from four "valid" characters. 350 final int i = 351 IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 352 | IA[sArr[sIx++]]; 353 354 // Add the bytes 355 dArr[d++] = (byte) (i >> 16); 356 dArr[d++] = (byte) (i >> 8); 357 dArr[d++] = (byte) i; 358 359 // If line separator, jump over it. 360 if (sepCnt > 0 && ++cc == 19) { 361 sIx += 2; 362 cc = 0; 363 } 364 } 365 366 if (d < len) { 367 // Decode last 1-3 bytes (incl '=') into 1-3 bytes 368 int i = 0; 369 for (int j = 0; sIx <= eIx - pad; j++) { 370 i |= IA[sArr[sIx++]] << 18 - j * 6; 371 } 372 373 for (int r = 16; d < len; r -= 8) { 374 dArr[d++] = (byte) (i >> r); 375 } 376 } 377 378 return dArr; 379 } 380 381 /** 382 * Decodes a BASE64 encoded char array that is known to be resonably well 383 * formatted. The method is about twice as fast as {@link #decode(char[])}. 384 * The preconditions are:<br> 385 * + The array must have a line length of 76 chars OR no line separators at 386 * all (one line).<br> 387 * + Line separator must be "\r\n", as specified in RFC 2045 + The array 388 * must not contain illegal characters within the encoded string<br> 389 * + The array CAN have illegal characters at the beginning and end, those 390 * will be dealt with appropriately.<br> 391 * 392 * @param sArr 393 * The source array. Length 0 will return an empty array. 394 * <code>null</code> will throw an exception. 395 * @return The decoded array of bytes. May be of length 0. 396 */ 397 public static byte[] decodeFast(final char[] sArr) { 398 // Check special case 399 final int sLen = sArr.length; 400 if (sLen == 0) { 401 return new byte[0]; 402 } 403 404 int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. 405 406 // Trim illegal chars from start 407 while (sIx < eIx && IA[sArr[sIx]] < 0) { 408 sIx++; 409 } 410 411 // Trim illegal chars from end 412 while (eIx > 0 && IA[sArr[eIx]] < 0) { 413 eIx--; 414 } 415 416 // get the padding count (=) (0, 1 or 2) 417 final int pad = sArr[eIx] == '=' ? sArr[eIx - 1] == '=' ? 2 : 1 : 0; // Count '=' at end. 418 final int cCnt = eIx - sIx + 1; // Content count including possible separators 419 final int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; 420 421 final int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes 422 final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length 423 424 // Decode all but the last 0 - 2 bytes. 425 int d = 0; 426 for (int cc = 0, eLen = len / 3 * 3; d < eLen;) { 427 // Assemble three bytes into an int from four "valid" characters. 428 final int i = 429 IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 430 | IA[sArr[sIx++]]; 431 432 // Add the bytes 433 dArr[d++] = (byte) (i >> 16); 434 dArr[d++] = (byte) (i >> 8); 435 dArr[d++] = (byte) i; 436 437 // If line separator, jump over it. 438 if (sepCnt > 0 && ++cc == 19) { 439 sIx += 2; 440 cc = 0; 441 } 442 } 443 444 if (d < len) { 445 // Decode last 1-3 bytes (incl '=') into 1-3 bytes 446 int i = 0; 447 for (int j = 0; sIx <= eIx - pad; j++) { 448 i |= IA[sArr[sIx++]] << 18 - j * 6; 449 } 450 451 for (int r = 16; d < len; r -= 8) { 452 dArr[d++] = (byte) (i >> r); 453 } 454 } 455 456 return dArr; 457 } 458 459 /** 460 * Decodes a BASE64 encoded string that is known to be resonably well 461 * formatted. The method is about twice as fast as {@link #decode(String)}. 462 * The preconditions are:<br> 463 * + The array must have a line length of 76 chars OR no line separators at 464 * all (one line).<br> 465 * + Line separator must be "\r\n", as specified in RFC 2045 + The array 466 * must not contain illegal characters within the encoded string<br> 467 * + The array CAN have illegal characters at the beginning and end, those 468 * will be dealt with appropriately.<br> 469 * 470 * @param s 471 * The source string. Length 0 will return an empty array. 472 * <code>null</code> will throw an exception. 473 * @return The decoded array of bytes. May be of length 0. 474 */ 475 public static byte[] decodeFast(final String s) { 476 // Check special case 477 final int sLen = s.length(); 478 if (sLen == 0) { 479 return new byte[0]; 480 } 481 482 int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. 483 484 // Trim illegal chars from start 485 while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) { 486 sIx++; 487 } 488 489 // Trim illegal chars from end 490 while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) { 491 eIx--; 492 } 493 494 // get the padding count (=) (0, 1 or 2) 495 final int pad = s.charAt(eIx) == '=' ? s.charAt(eIx - 1) == '=' ? 2 : 1 : 0; // Count '=' at end. 496 final int cCnt = eIx - sIx + 1; // Content count including possible separators 497 final int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; 498 499 final int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes 500 final byte[] dArr = new byte[len]; // Preallocate byte[] of exact length 501 502 // Decode all but the last 0 - 2 bytes. 503 int d = 0; 504 for (int cc = 0, eLen = len / 3 * 3; d < eLen;) { 505 // Assemble three bytes into an int from four "valid" characters. 506 final int i = 507 IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 508 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)]; 509 510 // Add the bytes 511 dArr[d++] = (byte) (i >> 16); 512 dArr[d++] = (byte) (i >> 8); 513 dArr[d++] = (byte) i; 514 515 // If line separator, jump over it. 516 if (sepCnt > 0 && ++cc == 19) { 517 sIx += 2; 518 cc = 0; 519 } 520 } 521 522 if (d < len) { 523 // Decode last 1-3 bytes (incl '=') into 1-3 bytes 524 int i = 0; 525 for (int j = 0; sIx <= eIx - pad; j++) { 526 i |= IA[s.charAt(sIx++)] << 18 - j * 6; 527 } 528 529 for (int r = 16; d < len; r -= 8) { 530 dArr[d++] = (byte) (i >> r); 531 } 532 } 533 534 return dArr; 535 } 536 537 /** 538 * This method is using {@link #encode(byte[], boolean)}, and it only exists 539 * so we don't break the API. 540 * 541 * @param content 542 * The bytearray that needs to be Base64 encoded 543 * @return the Base64 encoded 544 */ 545 public static String encode(final byte[] content) { 546 return encode(content, false); 547 } 548 549 /** 550 * Encodes a raw byte array into a BASE64 <code>String</code> representation 551 * i accordance with RFC 2045. 552 * 553 * @param sArr 554 * The bytes to convert. If <code>null</code> or length 0 an 555 * empty array will be returned. 556 * @param lineSep 557 * Optional "\r\n" after 76 characters, unless end of file.<br> 558 * No line separator will be in breach of RFC 2045 which 559 * specifies max 76 per line but will be a little faster. 560 * @return A BASE64 encoded array. Never <code>null</code>. 561 */ 562 public static String encode(final byte[] sArr, final boolean lineSep) { 563 /* 564 * Reuse char[] since we can't create a String incrementally anyway and 565 * StringBuffer/Builder would be slower. 566 */ 567 return new String(encodeToChar(sArr, lineSep)); 568 } 569 570 /** 571 * Encodes a raw byte array into a BASE64 <code>byte[]</code> representation 572 * i accordance with RFC 2045. 573 * 574 * @param sArr 575 * The bytes to convert. If <code>null</code> or length 0 an 576 * empty array will be returned. 577 * @param lineSep 578 * Optional "\r\n" after 76 characters, unless end of file.<br> 579 * No line separator will be in breach of RFC 2045 which 580 * specifies max 76 per line but will be a little faster. 581 * @return A BASE64 encoded array. Never <code>null</code>. 582 */ 583 public static byte[] encodeToByte(final byte[] sArr, final boolean lineSep) { 584 // Check special case 585 final int sLen = sArr != null ? sArr.length : 0; 586 if (sLen == 0) { 587 return new byte[0]; 588 } 589 590 final int eLen = sLen / 3 * 3; // Length of even 24-bits. 591 final int cCnt = (sLen - 1) / 3 + 1 << 2; // Returned character count 592 final int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array 593 final byte[] dArr = new byte[dLen]; 594 595 // Encode even 24-bits 596 for (int s = 0, d = 0, cc = 0; s < eLen;) { 597 // Copy next three bytes into lower 24 bits of int, paying attension to sign. 598 final int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | sArr[s++] & 0xff; 599 600 // Encode the int into four chars 601 dArr[d++] = (byte) CA[i >>> 18 & 0x3f]; 602 dArr[d++] = (byte) CA[i >>> 12 & 0x3f]; 603 dArr[d++] = (byte) CA[i >>> 6 & 0x3f]; 604 dArr[d++] = (byte) CA[i & 0x3f]; 605 606 // Add optional line separator 607 if (lineSep && ++cc == 19 && d < dLen - 2) { 608 dArr[d++] = '\r'; 609 dArr[d++] = '\n'; 610 cc = 0; 611 } 612 } 613 614 // Pad and encode last bits if source isn't an even 24 bits. 615 final int left = sLen - eLen; // 0 - 2. 616 if (left > 0) { 617 // Prepare the int 618 final int i = 619 (sArr[eLen] & 0xff) << 10 | (left == 2 ? (sArr[sLen - 1] & 0xff) << 2 : 0); 620 621 // Set last four chars 622 dArr[dLen - 4] = (byte) CA[i >> 12]; 623 dArr[dLen - 3] = (byte) CA[i >>> 6 & 0x3f]; 624 dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '='; 625 dArr[dLen - 1] = '='; 626 } 627 return dArr; 628 } 629 630 /** 631 * Encodes a raw byte array into a BASE64 <code>char[]</code> representation 632 * i accordance with RFC 2045. 633 * 634 * @param sArr 635 * The bytes to convert. If <code>null</code> or length 0 an 636 * empty array will be returned. 637 * @param lineSep 638 * Optional "\r\n" after 76 characters, unless end of file.<br> 639 * No line separator will be in breach of RFC 2045 which 640 * specifies max 76 per line but will be a little faster. 641 * @return A BASE64 encoded array. Never <code>null</code>. 642 */ 643 public static char[] encodeToChar(final byte[] sArr, final boolean lineSep) { 644 // Check special case 645 final int sLen = sArr != null ? sArr.length : 0; 646 if (sLen == 0) { 647 return new char[0]; 648 } 649 650 final int eLen = sLen / 3 * 3; // Length of even 24-bits. 651 final int cCnt = (sLen - 1) / 3 + 1 << 2; // Returned character count 652 final int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array 653 final char[] dArr = new char[dLen]; 654 655 // Encode even 24-bits 656 for (int s = 0, d = 0, cc = 0; s < eLen;) { 657 // Copy next three bytes into lower 24 bits of int, paying attension to sign. 658 final int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | sArr[s++] & 0xff; 659 660 // Encode the int into four chars 661 dArr[d++] = CA[i >>> 18 & 0x3f]; 662 dArr[d++] = CA[i >>> 12 & 0x3f]; 663 dArr[d++] = CA[i >>> 6 & 0x3f]; 664 dArr[d++] = CA[i & 0x3f]; 665 666 // Add optional line separator 667 if (lineSep && ++cc == 19 && d < dLen - 2) { 668 dArr[d++] = '\r'; 669 dArr[d++] = '\n'; 670 cc = 0; 671 } 672 } 673 674 // Pad and encode last bits if source isn't even 24 bits. 675 final int left = sLen - eLen; // 0 - 2. 676 if (left > 0) { 677 // Prepare the int 678 final int i = 679 (sArr[eLen] & 0xff) << 10 | (left == 2 ? (sArr[sLen - 1] & 0xff) << 2 : 0); 680 681 // Set last four chars 682 dArr[dLen - 4] = CA[i >> 12]; 683 dArr[dLen - 3] = CA[i >>> 6 & 0x3f]; 684 dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '='; 685 dArr[dLen - 1] = '='; 686 } 687 return dArr; 688 } 689 690 private Base64() { 691 // No impl. 692 } 693}