BASE64Encoder.java 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * FileName:BASE64Encoder.java
  3. * <p>
  4. * Copyright (c) 2017-2020, <a href="http://www.webcsn.com">hermit (794890569@qq.com)</a>.
  5. * <p>
  6. * Licensed under the GNU General Public License, Version 3 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. * <p>
  10. * http://www.gnu.org/licenses/gpl-3.0.html
  11. * <p>
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19. package cn.com.lzt.common.util.security;
  20. import java.io.*;
  21. /**
  22. * 密码器类
  23. *
  24. * @author ShenHuaJie
  25. * @since 2011-12-31
  26. */
  27. public class BASE64Encoder {
  28. /**
  29. * 译码数据源
  30. */
  31. private static final char[] PEM_ARRAY = {
  32. // 0 1 2 3 4 5 6 7
  33. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', // 0
  34. 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', // 1
  35. 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', // 2
  36. 'y', 'z', '1', '2', '3', '4', '5', '6', // 3
  37. '7', '8', '9', '0', 'A', 'B', 'C', 'D', // 4
  38. 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', // 5
  39. 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', // 6
  40. 'U', 'V', 'W', 'X', 'Y', 'Z', '+', '/' // 7
  41. };
  42. private static final byte[] pem_convert_array = new byte[256];
  43. private byte[] decode_buffer = new byte[4];
  44. public BASE64Encoder() {
  45. }
  46. /**
  47. * 编码
  48. */
  49. public String encode(byte[] bt) {
  50. int totalBits = bt.length * 8;
  51. int nn = totalBits % 6;
  52. int curPos = 0;// process bits
  53. StringBuilder toReturn = new StringBuilder(32);
  54. while (curPos < totalBits) {
  55. int bytePos = curPos / 8;
  56. switch (curPos % 8) {
  57. case 0:
  58. toReturn.append(PEM_ARRAY[(bt[bytePos] & 0xfc) >> 2]);
  59. break;
  60. case 2:
  61. toReturn.append(PEM_ARRAY[(bt[bytePos] & 0x3f)]);
  62. break;
  63. case 4:
  64. if (bytePos == bt.length - 1) {
  65. toReturn.append(PEM_ARRAY[((bt[bytePos] & 0x0f) << 2) & 0x3f]);
  66. } else {
  67. int pos = (((bt[bytePos] & 0x0f) << 2) | ((bt[bytePos + 1] & 0xc0) >> 6)) & 0x3f;
  68. toReturn.append(PEM_ARRAY[pos]);
  69. }
  70. break;
  71. case 6:
  72. if (bytePos == bt.length - 1) {
  73. toReturn.append(PEM_ARRAY[((bt[bytePos] & 0x03) << 4) & 0x3f]);
  74. } else {
  75. int pos = (((bt[bytePos] & 0x03) << 4) | ((bt[bytePos + 1] & 0xf0) >> 4)) & 0x3f;
  76. toReturn.append(PEM_ARRAY[pos]);
  77. }
  78. break;
  79. default:
  80. break;
  81. }
  82. curPos += 6;
  83. }
  84. if (nn == 2) {
  85. toReturn.append("==");
  86. } else if (nn == 4) {
  87. toReturn.append("=");
  88. }
  89. return toReturn.toString();
  90. }
  91. /**
  92. * 解码
  93. */
  94. public byte[] decode(String str) throws IOException {
  95. byte[] arrayOfByte = str.getBytes();
  96. ByteArrayInputStream inputStream = new ByteArrayInputStream(arrayOfByte);
  97. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  98. decodeBuffer(inputStream, outputStream);
  99. return outputStream.toByteArray();
  100. }
  101. private void decodeBuffer(InputStream paramInputStream, OutputStream paramOutputStream) throws IOException {
  102. PushbackInputStream localPushbackInputStream = new PushbackInputStream(paramInputStream);
  103. int j = 0;
  104. while (true) {
  105. try {
  106. int k = bytesPerLine();
  107. int i = 0;
  108. if (i + bytesPerAtom() < k) {
  109. decodeAtom(localPushbackInputStream, paramOutputStream, bytesPerAtom());
  110. j += bytesPerAtom();
  111. i += bytesPerAtom();
  112. continue;
  113. }
  114. if (i + bytesPerAtom() == k) {
  115. decodeAtom(localPushbackInputStream, paramOutputStream, bytesPerAtom());
  116. j += bytesPerAtom();
  117. } else {
  118. decodeAtom(localPushbackInputStream, paramOutputStream, k - i);
  119. j += k - i;
  120. }
  121. } catch (RuntimeException e) {
  122. String.valueOf(j);
  123. break;
  124. }
  125. }
  126. }
  127. private int bytesPerAtom() {
  128. return 4;
  129. }
  130. private int bytesPerLine() {
  131. return 72;
  132. }
  133. private void decodeAtom(PushbackInputStream paramPushbackInputStream, OutputStream paramOutputStream, int paramInt)
  134. throws IOException {
  135. int i;
  136. int j = -1;
  137. int k = -1;
  138. int m = -1;
  139. int n = -1;
  140. if (paramInt < 2) {
  141. throw new ArrayStoreException("BASE64Decoder: Not enough bytes for an atom.");
  142. }
  143. do {
  144. i = paramPushbackInputStream.read();
  145. if (i == -1) {
  146. throw new RuntimeException();
  147. }
  148. } while ((i == 10) || (i == 13));
  149. this.decode_buffer[0] = (byte)i;
  150. i = readFully(paramPushbackInputStream, this.decode_buffer, 1, paramInt - 1);
  151. if (i == -1) {
  152. throw new RuntimeException();
  153. }
  154. if ((paramInt > 3) && (this.decode_buffer[3] == 61)) {
  155. paramInt = 3;
  156. }
  157. if ((paramInt > 2) && (this.decode_buffer[2] == 61)) {
  158. paramInt = 2;
  159. }
  160. switch (paramInt) {
  161. case 4:
  162. n = pem_convert_array[(this.decode_buffer[3] & 0xFF)];
  163. case 3:
  164. m = pem_convert_array[(this.decode_buffer[2] & 0xFF)];
  165. case 2:
  166. k = pem_convert_array[(this.decode_buffer[1] & 0xFF)];
  167. j = pem_convert_array[(this.decode_buffer[0] & 0xFF)];
  168. }
  169. switch (paramInt) {
  170. case 2:
  171. paramOutputStream.write((byte)(j << 2 & 0xFC | k >>> 4 & 0x3));
  172. break;
  173. case 3:
  174. paramOutputStream.write((byte)(j << 2 & 0xFC | k >>> 4 & 0x3));
  175. paramOutputStream.write((byte)(k << 4 & 0xF0 | m >>> 2 & 0xF));
  176. break;
  177. case 4:
  178. paramOutputStream.write((byte)(j << 2 & 0xFC | k >>> 4 & 0x3));
  179. paramOutputStream.write((byte)(k << 4 & 0xF0 | m >>> 2 & 0xF));
  180. paramOutputStream.write((byte)(m << 6 & 0xC0 | n & 0x3F));
  181. }
  182. }
  183. private int readFully(InputStream paramInputStream, byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  184. throws IOException {
  185. for (int i = 0; i < paramInt2; i++) {
  186. int j = paramInputStream.read();
  187. if (j == -1) {
  188. return i == 0 ? -1 : i;
  189. }
  190. paramArrayOfByte[(i + paramInt1)] = (byte)j;
  191. }
  192. return paramInt2;
  193. }
  194. static {
  195. for (int i = 0; i < 255; i++) {
  196. pem_convert_array[i] = -1;
  197. }
  198. for (int i = 0; i < PEM_ARRAY.length; i++)
  199. pem_convert_array[PEM_ARRAY[i]] = (byte)i;
  200. }
  201. }