/src/main/java/com/alibaba/fastjson/util/Base64.java

https://github.com/alibaba/fastjson · Java · 210 lines · 116 code · 39 blank · 55 comment · 49 complexity · 0c20fc7fca845718e2693edba14d41d3 MD5 · raw file

  1. package com.alibaba.fastjson.util;
  2. import java.util.Arrays;
  3. /**
  4. *
  5. * @version 2.2
  6. * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11
  7. * @deprecated internal api, don't use.
  8. */
  9. public class Base64 {
  10. public static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
  11. public static final int[] IA = new int[256];
  12. static {
  13. Arrays.fill(IA, -1);
  14. for (int i = 0, iS = CA.length; i < iS; i++)
  15. IA[CA[i]] = i;
  16. IA['='] = 0;
  17. }
  18. /**
  19. * Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as
  20. * fast as #decode(char[]). The preconditions are:<br>
  21. * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
  22. * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within
  23. * the encoded string<br>
  24. * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
  25. *
  26. * @param chars The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
  27. * @return The decoded array of bytes. May be of length 0.
  28. */
  29. public static byte[] decodeFast(char[] chars, int offset, int charsLen) {
  30. // Check special case
  31. if (charsLen == 0) {
  32. return new byte[0];
  33. }
  34. int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming.
  35. // Trim illegal chars from start
  36. while (sIx < eIx && IA[chars[sIx]] < 0)
  37. sIx++;
  38. // Trim illegal chars from end
  39. while (eIx > 0 && IA[chars[eIx]] < 0)
  40. eIx--;
  41. // get the padding count (=) (0, 1 or 2)
  42. int pad = chars[eIx] == '=' ? (chars[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
  43. int cCnt = eIx - sIx + 1; // Content count including possible separators
  44. int sepCnt = charsLen > 76 ? (chars[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
  45. int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
  46. byte[] bytes = new byte[len]; // Preallocate byte[] of exact length
  47. // Decode all but the last 0 - 2 bytes.
  48. int d = 0;
  49. for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
  50. // Assemble three bytes into an int from four "valid" characters.
  51. int i = IA[chars[sIx++]] << 18 | IA[chars[sIx++]] << 12 | IA[chars[sIx++]] << 6 | IA[chars[sIx++]];
  52. // Add the bytes
  53. bytes[d++] = (byte) (i >> 16);
  54. bytes[d++] = (byte) (i >> 8);
  55. bytes[d++] = (byte) i;
  56. // If line separator, jump over it.
  57. if (sepCnt > 0 && ++cc == 19) {
  58. sIx += 2;
  59. cc = 0;
  60. }
  61. }
  62. if (d < len) {
  63. // Decode last 1-3 bytes (incl '=') into 1-3 bytes
  64. int i = 0;
  65. for (int j = 0; sIx <= eIx - pad; j++)
  66. i |= IA[chars[sIx++]] << (18 - j * 6);
  67. for (int r = 16; d < len; r -= 8)
  68. bytes[d++] = (byte) (i >> r);
  69. }
  70. return bytes;
  71. }
  72. public static byte[] decodeFast(String chars, int offset, int charsLen) {
  73. // Check special case
  74. if (charsLen == 0) {
  75. return new byte[0];
  76. }
  77. int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming.
  78. // Trim illegal chars from start
  79. while (sIx < eIx && IA[chars.charAt(sIx)] < 0)
  80. sIx++;
  81. // Trim illegal chars from end
  82. while (eIx > 0 && IA[chars.charAt(eIx)] < 0)
  83. eIx--;
  84. // get the padding count (=) (0, 1 or 2)
  85. int pad = chars.charAt(eIx) == '=' ? (chars.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
  86. int cCnt = eIx - sIx + 1; // Content count including possible separators
  87. int sepCnt = charsLen > 76 ? (chars.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
  88. int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
  89. byte[] bytes = new byte[len]; // Preallocate byte[] of exact length
  90. // Decode all but the last 0 - 2 bytes.
  91. int d = 0;
  92. for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
  93. // Assemble three bytes into an int from four "valid" characters.
  94. int i = IA[chars.charAt(sIx++)] << 18 | IA[chars.charAt(sIx++)] << 12 | IA[chars.charAt(sIx++)] << 6 | IA[chars.charAt(sIx++)];
  95. // Add the bytes
  96. bytes[d++] = (byte) (i >> 16);
  97. bytes[d++] = (byte) (i >> 8);
  98. bytes[d++] = (byte) i;
  99. // If line separator, jump over it.
  100. if (sepCnt > 0 && ++cc == 19) {
  101. sIx += 2;
  102. cc = 0;
  103. }
  104. }
  105. if (d < len) {
  106. // Decode last 1-3 bytes (incl '=') into 1-3 bytes
  107. int i = 0;
  108. for (int j = 0; sIx <= eIx - pad; j++)
  109. i |= IA[chars.charAt(sIx++)] << (18 - j * 6);
  110. for (int r = 16; d < len; r -= 8)
  111. bytes[d++] = (byte) (i >> r);
  112. }
  113. return bytes;
  114. }
  115. /**
  116. * Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as fast
  117. * as decode(String). The preconditions are:<br>
  118. * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
  119. * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within
  120. * the encoded string<br>
  121. * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
  122. *
  123. * @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception.
  124. * @return The decoded array of bytes. May be of length 0.
  125. */
  126. public static byte[] decodeFast(String s) {
  127. // Check special case
  128. int sLen = s.length();
  129. if (sLen == 0) {
  130. return new byte[0];
  131. }
  132. int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
  133. // Trim illegal chars from start
  134. while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0)
  135. sIx++;
  136. // Trim illegal chars from end
  137. while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0)
  138. eIx--;
  139. // get the padding count (=) (0, 1 or 2)
  140. int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
  141. int cCnt = eIx - sIx + 1; // Content count including possible separators
  142. int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
  143. int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
  144. byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
  145. // Decode all but the last 0 - 2 bytes.
  146. int d = 0;
  147. for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
  148. // Assemble three bytes into an int from four "valid" characters.
  149. int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6
  150. | IA[s.charAt(sIx++)];
  151. // Add the bytes
  152. dArr[d++] = (byte) (i >> 16);
  153. dArr[d++] = (byte) (i >> 8);
  154. dArr[d++] = (byte) i;
  155. // If line separator, jump over it.
  156. if (sepCnt > 0 && ++cc == 19) {
  157. sIx += 2;
  158. cc = 0;
  159. }
  160. }
  161. if (d < len) {
  162. // Decode last 1-3 bytes (incl '=') into 1-3 bytes
  163. int i = 0;
  164. for (int j = 0; sIx <= eIx - pad; j++)
  165. i |= IA[s.charAt(sIx++)] << (18 - j * 6);
  166. for (int r = 16; d < len; r -= 8)
  167. dArr[d++] = (byte) (i >> r);
  168. }
  169. return dArr;
  170. }
  171. }