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