PageRenderTime 58ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/core/src/main/java/org/glassfish/tyrus/core/Base64Utils.java

https://github.com/JoshiManjila/tyrus
Java | 547 lines | 277 code | 82 blank | 188 comment | 116 complexity | c0a6fa90863feb7588bb24b882ed8730 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause-No-Nuclear-License-2014
  1. /*
  2. * Copyright (c) 2004-2013 Oracle and/or its affiliates. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * - Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * - Neither the name of Oracle nor the names of its
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  20. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. package org.glassfish.tyrus.core;
  32. import java.util.Arrays;
  33. public class Base64Utils {
  34. private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
  35. private static final int[] IA = new int[256];
  36. static {
  37. Arrays.fill(IA, -1);
  38. for (int i = 0, iS = CA.length; i < iS; i++)
  39. IA[CA[i]] = i;
  40. IA['='] = 0;
  41. }
  42. // ****************************************************************************************
  43. // * char[] version
  44. // ****************************************************************************************
  45. /**
  46. * Encodes a raw byte array into a BASE64 <code>char[]</code> representation i accordance with RFC 2045.
  47. *
  48. * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
  49. * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
  50. * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
  51. * little faster.
  52. * @return A BASE64 encoded array. Never <code>null</code>.
  53. */
  54. public static char[] encodeToChar(byte[] sArr, boolean lineSep) {
  55. // Check special case
  56. int sLen = sArr != null ? sArr.length : 0;
  57. if (sLen == 0)
  58. return new char[0];
  59. int eLen = (sLen / 3) * 3; // Length of even 24-bits.
  60. int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
  61. int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
  62. char[] dArr = new char[dLen];
  63. // Encode even 24-bits
  64. for (int s = 0, d = 0, cc = 0; s < eLen; ) {
  65. // Copy next three bytes into lower 24 bits of int, paying attention to sign.
  66. int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
  67. // Encode the int into four chars
  68. dArr[d++] = CA[(i >>> 18) & 0x3f];
  69. dArr[d++] = CA[(i >>> 12) & 0x3f];
  70. dArr[d++] = CA[(i >>> 6) & 0x3f];
  71. dArr[d++] = CA[i & 0x3f];
  72. // Add optional line separator
  73. if (lineSep && ++cc == 19 && d < dLen - 2) {
  74. dArr[d++] = '\r';
  75. dArr[d++] = '\n';
  76. cc = 0;
  77. }
  78. }
  79. // Pad and encode last bits if source isn't even 24 bits.
  80. int left = sLen - eLen; // 0 - 2.
  81. if (left > 0) {
  82. // Prepare the int
  83. int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
  84. // Set last four chars
  85. dArr[dLen - 4] = CA[i >> 12];
  86. dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
  87. dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
  88. dArr[dLen - 1] = '=';
  89. }
  90. return dArr;
  91. }
  92. /**
  93. * Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with
  94. * and without line separators.
  95. *
  96. * @param sArr The source array. <code>null</code> or length 0 will return an empty array.
  97. * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
  98. * (including '=') isn't divisible by 4. (I.e. definitely corrupted).
  99. */
  100. public static byte[] decode(char[] sArr) {
  101. // Check special case
  102. int sLen = sArr != null ? sArr.length : 0;
  103. if (sLen == 0)
  104. return new byte[0];
  105. // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
  106. // so we don't have to reallocate & copy it later.
  107. int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
  108. 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.
  109. if (IA[sArr[i]] < 0)
  110. sepCnt++;
  111. // Check so that legal chars (including '=') are evenly divisible by 4 as specified in RFC 2045.
  112. if ((sLen - sepCnt) % 4 != 0)
  113. return null;
  114. int pad = 0;
  115. for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0; )
  116. if (sArr[i] == '=')
  117. pad++;
  118. int len = ((sLen - sepCnt) * 6 >> 3) - pad;
  119. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  120. for (int s = 0, d = 0; d < len; ) {
  121. // Assemble three bytes into an int from four "valid" characters.
  122. int i = 0;
  123. for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
  124. int c = IA[sArr[s++]];
  125. if (c >= 0)
  126. i |= c << (18 - j * 6);
  127. else
  128. j--;
  129. }
  130. // Add the bytes
  131. dArr[d++] = (byte) (i >> 16);
  132. if (d < len) {
  133. dArr[d++] = (byte) (i >> 8);
  134. if (d < len)
  135. dArr[d++] = (byte) i;
  136. }
  137. }
  138. return dArr;
  139. }
  140. /**
  141. * Decodes a BASE64 encoded char array that is known to be reasonably well formatted. The method is about twice as
  142. * fast as {@link #decode(char[])}. The preconditions are:<br>
  143. * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
  144. * + Line separator must be "\r\n", as specified in RFC 2045
  145. * + The array must not contain illegal characters within the encoded string<br>
  146. * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
  147. *
  148. * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
  149. * @return The decoded array of bytes. May be of length 0.
  150. */
  151. public static byte[] decodeFast(char[] sArr) {
  152. // Check special case
  153. int sLen = sArr.length;
  154. if (sLen == 0)
  155. return new byte[0];
  156. int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
  157. // Trim illegal chars from start
  158. while (sIx < eIx && IA[sArr[sIx]] < 0)
  159. sIx++;
  160. // Trim illegal chars from end
  161. while (eIx > 0 && IA[sArr[eIx]] < 0)
  162. eIx--;
  163. // get the padding count (=) (0, 1 or 2)
  164. int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
  165. int cCnt = eIx - sIx + 1; // Content count including possible separators
  166. int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
  167. int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
  168. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  169. // Decode all but the last 0 - 2 bytes.
  170. int d = 0;
  171. for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
  172. // Assemble three bytes into an int from four "valid" characters.
  173. int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
  174. // Add the bytes
  175. dArr[d++] = (byte) (i >> 16);
  176. dArr[d++] = (byte) (i >> 8);
  177. dArr[d++] = (byte) i;
  178. // If line separator, jump over it.
  179. if (sepCnt > 0 && ++cc == 19) {
  180. sIx += 2;
  181. cc = 0;
  182. }
  183. }
  184. if (d < len) {
  185. // Decode last 1-3 bytes (incl '=') into 1-3 bytes
  186. int i = 0;
  187. for (int j = 0; sIx <= eIx - pad; j++)
  188. i |= IA[sArr[sIx++]] << (18 - j * 6);
  189. for (int r = 16; d < len; r -= 8)
  190. dArr[d++] = (byte) (i >> r);
  191. }
  192. return dArr;
  193. }
  194. // ****************************************************************************************
  195. // * byte[] version
  196. // ****************************************************************************************
  197. /**
  198. * Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045.
  199. *
  200. * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
  201. * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
  202. * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
  203. * little faster.
  204. * @return A BASE64 encoded array. Never <code>null</code>.
  205. */
  206. public static byte[] encodeToByte(byte[] sArr, boolean lineSep) {
  207. // Check special case
  208. int sLen = sArr != null ? sArr.length : 0;
  209. if (sLen == 0)
  210. return new byte[0];
  211. int eLen = (sLen / 3) * 3; // Length of even 24-bits.
  212. int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
  213. int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
  214. byte[] dArr = new byte[dLen];
  215. // Encode even 24-bits
  216. for (int s = 0, d = 0, cc = 0; s < eLen; ) {
  217. // Copy next three bytes into lower 24 bits of int, paying attention to sign.
  218. int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
  219. // Encode the int into four chars
  220. dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
  221. dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
  222. dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
  223. dArr[d++] = (byte) CA[i & 0x3f];
  224. // Add optional line separator
  225. if (lineSep && ++cc == 19 && d < dLen - 2) {
  226. dArr[d++] = '\r';
  227. dArr[d++] = '\n';
  228. cc = 0;
  229. }
  230. }
  231. // Pad and encode last bits if source isn't an even 24 bits.
  232. int left = sLen - eLen; // 0 - 2.
  233. if (left > 0) {
  234. // Prepare the int
  235. int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
  236. // Set last four chars
  237. dArr[dLen - 4] = (byte) CA[i >> 12];
  238. dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
  239. dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
  240. dArr[dLen - 1] = '=';
  241. }
  242. return dArr;
  243. }
  244. /**
  245. * Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with
  246. * and without line separators.
  247. *
  248. * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
  249. * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
  250. * (including '=') isn't divisible by 4. (I.e. definitely corrupted).
  251. */
  252. public static byte[] decode(byte[] sArr) {
  253. // Check special case
  254. int sLen = sArr.length;
  255. // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
  256. // so we don't have to reallocate & copy it later.
  257. int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
  258. 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.
  259. if (IA[sArr[i] & 0xff] < 0)
  260. sepCnt++;
  261. // Check so that legal chars (including '=') are evenly divisible by 4 as specified in RFC 2045.
  262. if ((sLen - sepCnt) % 4 != 0)
  263. return null;
  264. int pad = 0;
  265. for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0; )
  266. if (sArr[i] == '=')
  267. pad++;
  268. int len = ((sLen - sepCnt) * 6 >> 3) - pad;
  269. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  270. for (int s = 0, d = 0; d < len; ) {
  271. // Assemble three bytes into an int from four "valid" characters.
  272. int i = 0;
  273. for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
  274. int c = IA[sArr[s++] & 0xff];
  275. if (c >= 0)
  276. i |= c << (18 - j * 6);
  277. else
  278. j--;
  279. }
  280. // Add the bytes
  281. dArr[d++] = (byte) (i >> 16);
  282. if (d < len) {
  283. dArr[d++] = (byte) (i >> 8);
  284. if (d < len)
  285. dArr[d++] = (byte) i;
  286. }
  287. }
  288. return dArr;
  289. }
  290. /**
  291. * Decodes a BASE64 encoded byte array that is known to be reasonably well formatted. The method is about twice as
  292. * fast as {@link #decode(byte[])}. The preconditions are:<br>
  293. * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
  294. * + Line separator must be "\r\n", as specified in RFC 2045
  295. * + The array must not contain illegal characters within the encoded string<br>
  296. * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
  297. *
  298. * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
  299. * @return The decoded array of bytes. May be of length 0.
  300. */
  301. public static byte[] decodeFast(byte[] sArr) {
  302. // Check special case
  303. int sLen = sArr.length;
  304. if (sLen == 0)
  305. return new byte[0];
  306. int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
  307. // Trim illegal chars from start
  308. while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
  309. sIx++;
  310. // Trim illegal chars from end
  311. while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
  312. eIx--;
  313. // get the padding count (=) (0, 1 or 2)
  314. int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
  315. int cCnt = eIx - sIx + 1; // Content count including possible separators
  316. int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
  317. int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
  318. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  319. // Decode all but the last 0 - 2 bytes.
  320. int d = 0;
  321. for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
  322. // Assemble three bytes into an int from four "valid" characters.
  323. int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
  324. // Add the bytes
  325. dArr[d++] = (byte) (i >> 16);
  326. dArr[d++] = (byte) (i >> 8);
  327. dArr[d++] = (byte) i;
  328. // If line separator, jump over it.
  329. if (sepCnt > 0 && ++cc == 19) {
  330. sIx += 2;
  331. cc = 0;
  332. }
  333. }
  334. if (d < len) {
  335. // Decode last 1-3 bytes (incl '=') into 1-3 bytes
  336. int i = 0;
  337. for (int j = 0; sIx <= eIx - pad; j++)
  338. i |= IA[sArr[sIx++]] << (18 - j * 6);
  339. for (int r = 16; d < len; r -= 8)
  340. dArr[d++] = (byte) (i >> r);
  341. }
  342. return dArr;
  343. }
  344. // ****************************************************************************************
  345. // * String version
  346. // ****************************************************************************************
  347. /**
  348. * Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045.
  349. *
  350. * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
  351. * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
  352. * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
  353. * little faster.
  354. * @return A BASE64 encoded array. Never <code>null</code>.
  355. */
  356. public static String encodeToString(byte[] sArr, boolean lineSep) {
  357. // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
  358. return new String(encodeToChar(sArr, lineSep));
  359. }
  360. /**
  361. * Decodes a BASE64 encoded <code>String</code>. All illegal characters will be ignored and can handle both strings with
  362. * and without line separators.<br>
  363. * <b>Note!</b> It can be up to about 2x the speed to call <code>decode(str.toCharArray())</code> instead. That
  364. * will create a temporary array though. This version will use <code>str.charAt(i)</code> to iterate the string.
  365. *
  366. * @param str The source string. <code>null</code> or length 0 will return an empty array.
  367. * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
  368. * (including '=') isn't divisible by 4. (I.e. definitely corrupted).
  369. */
  370. public static byte[] decode(String str) {
  371. // Check special case
  372. int sLen = str != null ? str.length() : 0;
  373. if (sLen == 0)
  374. return new byte[0];
  375. // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
  376. // so we don't have to reallocate & copy it later.
  377. int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
  378. 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.
  379. if (IA[str.charAt(i)] < 0)
  380. sepCnt++;
  381. // Check so that legal chars (including '=') are evenly divisible by 4 as specified in RFC 2045.
  382. if ((sLen - sepCnt) % 4 != 0)
  383. return null;
  384. // Count '=' at end
  385. int pad = 0;
  386. for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0; )
  387. if (str.charAt(i) == '=')
  388. pad++;
  389. int len = ((sLen - sepCnt) * 6 >> 3) - pad;
  390. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  391. for (int s = 0, d = 0; d < len; ) {
  392. // Assemble three bytes into an int from four "valid" characters.
  393. int i = 0;
  394. for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
  395. int c = IA[str.charAt(s++)];
  396. if (c >= 0)
  397. i |= c << (18 - j * 6);
  398. else
  399. j--;
  400. }
  401. // Add the bytes
  402. dArr[d++] = (byte) (i >> 16);
  403. if (d < len) {
  404. dArr[d++] = (byte) (i >> 8);
  405. if (d < len)
  406. dArr[d++] = (byte) i;
  407. }
  408. }
  409. return dArr;
  410. }
  411. /**
  412. * Decodes a BASE64 encoded string that is known to be reasonably well formatted. The method is about twice as
  413. * fast as {@link #decode(String)}. The preconditions are:<br>
  414. * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
  415. * + Line separator must be "\r\n", as specified in RFC 2045
  416. * + The array must not contain illegal characters within the encoded string<br>
  417. * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
  418. *
  419. * @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception.
  420. * @return The decoded array of bytes. May be of length 0.
  421. */
  422. public static byte[] decodeFast(String s) {
  423. // Check special case
  424. int sLen = s.length();
  425. if (sLen == 0)
  426. return new byte[0];
  427. int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
  428. // Trim illegal chars from start
  429. while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0)
  430. sIx++;
  431. // Trim illegal chars from end
  432. while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0)
  433. eIx--;
  434. // get the padding count (=) (0, 1 or 2)
  435. int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
  436. int cCnt = eIx - sIx + 1; // Content count including possible separators
  437. int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
  438. int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
  439. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  440. // Decode all but the last 0 - 2 bytes.
  441. int d = 0;
  442. for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
  443. // Assemble three bytes into an int from four "valid" characters.
  444. int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)];
  445. // Add the bytes
  446. dArr[d++] = (byte) (i >> 16);
  447. dArr[d++] = (byte) (i >> 8);
  448. dArr[d++] = (byte) i;
  449. // If line separator, jump over it.
  450. if (sepCnt > 0 && ++cc == 19) {
  451. sIx += 2;
  452. cc = 0;
  453. }
  454. }
  455. if (d < len) {
  456. // Decode last 1-3 bytes (incl '=') into 1-3 bytes
  457. int i = 0;
  458. for (int j = 0; sIx <= eIx - pad; j++)
  459. i |= IA[s.charAt(sIx++)] << (18 - j * 6);
  460. for (int r = 16; d < len; r -= 8)
  461. dArr[d++] = (byte) (i >> r);
  462. }
  463. return dArr;
  464. }
  465. }