Base64.java 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package com.yihu.ehr.util.encode;
  2. /**
  3. * 标准Base64编解码,具体规范请参见相关文档。
  4. */
  5. public class Base64 {
  6. /** Base64编码表。*/
  7. private static char Base64Code[] = {
  8. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
  9. 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
  10. 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
  11. 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
  12. };
  13. /** Base64解码表。*/
  14. private static byte Base64Decode[] = {
  15. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  16. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, //注意两个63,为兼容SMP,
  17. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,63,-1,63, //“/”和“-”都翻译成63。
  18. 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1,
  19. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, //注意两个0:
  20. 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, //“A”和“=”都翻译成0。
  21. -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
  22. 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
  23. };
  24. /**
  25. * 构造方法私有化,防止实例化。
  26. */
  27. private Base64() {}
  28. /**
  29. * Base64编码。将字节数组中字节3个一组编码成4个可见字符。
  30. * @param b 需要被编码的字节数据。
  31. * @return 编码后的Base64字符串。
  32. */
  33. public static String encode(byte[] b) {
  34. int code = 0;
  35. //按实际编码后长度开辟内存,加快速度
  36. StringBuffer sb =new StringBuffer(((b.length-1)/3)<<2+4);
  37. //进行编码
  38. for (int i=0;i<b.length;i++) {
  39. code|=(b[i]<<(16-i%3*8)) & (0xff<<(16-i%3*8));
  40. if (i%3==2 || i==b.length-1) {
  41. sb.append(Base64Code[(code & 0xfc0000) >>> 18 ]);
  42. sb.append(Base64Code[(code & 0x3f000) >>> 12 ]);
  43. sb.append(Base64Code[(code & 0xfc0) >>> 6 ]);
  44. sb.append(Base64Code[ code & 0x3f ]);
  45. code=0;
  46. }
  47. }
  48. //对于长度非3的整数倍的字节数组,编码前先补0,编码后结尾处编码用=代替,
  49. //=的个数和短缺的长度一致,以此来标识出数据实际长度
  50. if (b.length%3>0) {
  51. sb.setCharAt(sb.length()-1,'=');
  52. }
  53. if (b.length%3==1) {
  54. sb.setCharAt(sb.length()-2,'=');
  55. }
  56. return sb.toString();
  57. }
  58. /**
  59. * Base64解码。
  60. * @param code 用Base64编码的ASCII字符串
  61. * @return 解码后的字节数据
  62. */
  63. public static byte[] decode(String code) {
  64. //检查参数合法性
  65. if (code==null) {
  66. return null;
  67. }
  68. int len = code.length();
  69. if (len%4!=0) {
  70. throw new IllegalArgumentException("Base64 string length must be 4*n");
  71. }
  72. if (code.length()==0){
  73. return new byte[0];
  74. }
  75. //统计填充的等号个数
  76. int pad = 0;
  77. if (code.charAt(len-1)=='=') {
  78. pad++;
  79. }
  80. if (code.charAt(len-2)=='=') {
  81. pad++;
  82. }
  83. //根据填充等号的个数来计算实际数据长度
  84. int retLen = len/4*3 - pad;
  85. //分配字节数组空间
  86. byte[] ret = new byte [retLen];
  87. //查表解码
  88. char ch1,ch2,ch3,ch4;
  89. int i;
  90. for (i=0;i<len;i+=4) {
  91. int j=i/4*3;
  92. ch1 = code.charAt(i);
  93. ch2 = code.charAt(i+1);
  94. ch3 = code.charAt(i+2);
  95. ch4 = code.charAt(i+3);
  96. int tmp = (Base64Decode[ch1]<<18)|(Base64Decode[ch2]<<12)
  97. |(Base64Decode[ch3]<<6)|(Base64Decode[ch4]);
  98. ret[j] = (byte) ((tmp&0xff0000) >> 16);
  99. if (i<len-4) {
  100. ret[j+1] = (byte) ((tmp&0x00ff00) >> 8);
  101. ret[j+2] =(byte) ((tmp&0x0000ff));
  102. }
  103. else {
  104. if(j+1<retLen) {
  105. ret[j+1] = (byte) ((tmp&0x00ff00) >> 8);
  106. }
  107. if(j+2<retLen) {
  108. ret[j+2] = (byte) ((tmp&0x0000ff));
  109. }
  110. }
  111. }
  112. return ret;
  113. }
  114. }