自己写的一个base64转换用途Java程序

看看代码
  1 import java.io.ByteArrayOutputStream;
  2 import java.io.IOException;
  3 import java.io.StringWriter;
  4 import java.util.Arrays;
  5 import java.util.HashMap;
  6 import java.util.Map;
  7 
  8 public class MyBase64 {
  9     private static final char[] set = ".0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
 10             .toCharArray();
 11     /*
 12      * 结尾表示填充0x0字符数目
 13      */
 14     static final char blank = '-';
 15     /*
 16      * 间隔三个字符分段
 17      */
 18     static final int step = 3;
 19     /*
 20      * 源数组结尾填0
 21      */
 22     static final byte fill = 0x0;
 23 
 24     private static MyBase64A myBase64 = null;
 25 
 26     public static MyBase64A getInstance() {
 27         if (myBase64 == null) {
 28             synchronized (MyBase64A.class) {
 29                 if (myBase64 == null) {
 30                     myBase64 = new MyBase64A();
 31                 }
 32             }
 33         }
 34         return myBase64;
 35         // return threadLocal.get();
 36     }
 37 
 38     private static Map<Character, Integer> initMap() {
 39         Map<Character, Integer> hashMap = new HashMap<Character, Integer>(
 40                 set.length);
 41         for (int i = 0; i < set.length; i++) {
 42             hashMap.put(set[i], i);
 43         }
 44         return hashMap;
 45     }
 46 
 47     private final Map<Character, Integer> map;
 48 
 49     private MyBase64A() {
 50         map = initMap();
 51     }
 52 
 53     public byte[] reverseTrans(String string) throws IOException {
 54         char[] chars = string.toCharArray();
 55 
 56         final int step = 4;
 57 
 58         int approximation = chars.length * 3 / 4;
 59         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
 60                 approximation);
 61 
 62         long swap;
 63         char c1, c2, c3, c4;
 64         byte b1, b2, b3;
 65 
 66         int begin = 0;
 67         int end = chars.length;
 68 
 69         int offset = begin;
 70         while (offset + 3 < end) {
 71             c1 = chars[offset];
 72             c2 = chars[offset + 1];
 73             c3 = chars[offset + 2];
 74             c4 = chars[offset + 3];
 75 
 76             swap = (map.get(c1) & 0xff) << 18 | (map.get(c2) & 0xff) << 12
 77                     | (map.get(c3) & 0xff) << 6 | (map.get(c4) & 0xff);
 78 
 79             b1 = (byte) ((swap >> 16) & 0xff);
 80             b2 = (byte) ((swap >> 8) & 0xff);
 81             b3 = (byte) (swap & 0xff);
 82 
 83             byteArrayOutputStream.write(b1);
 84             byteArrayOutputStream.write(b2);
 85             byteArrayOutputStream.write(b3);
 86 
 87             offset += step;
 88         }
 89         // logger.debug(end - offset);
 90         byte[] bytes = Arrays.copyOf(byteArrayOutputStream.toByteArray(),
 91                 byteArrayOutputStream.size() - (end - offset));
 92         return bytes;
 93     }
 94 
 95     /**
 96      * 
 97      * @param source
 98      *            总之是一个字节队列。
 99      * @return url相容的 自制 base64编码
100      */
101     public String trans(byte[] source) {
102         int begin = 0, end = source.length;
103         /*
104          * (source.length + 2) / 3 处以三,余数上限取整。 + 2 , 可能追加至多两个填充占位符。
105          */
106         int approximation = (source.length + 2) / 3 * 4 + 2;
107         StringWriter stringWriter = new StringWriter(approximation);
108 
109         int offset;
110         long swap;
111         byte a, b, c;
112         int num1, num2, num3, num4;
113         int app = 0;
114 
115         offset = begin;
116         while (offset < end) {
117             a = source[offset];
118             if (offset + 1 < end) {
119                 b = source[offset + 1];
120             } else {
121                 b = fill;
122                 app++;
123             }
124             if (offset + 2 < end) {
125                 c = source[offset + 2];
126             } else {
127                 c = fill;
128                 app++;
129             }
130 
131             swap = ((a & 0xff) << 16) | ((b & 0xff) << 8) | c & 0xff;
132 
133             // logger.debug(String.format("%x", swap));
134 
135             num1 = (int) ((swap >> 18) & 63);
136             num2 = (int) ((swap >> 12) & 63);
137             num3 = (int) ((swap >> 6) & 63);
138             num4 = (int) (swap & 63);
139 
140             stringWriter.append(set[num1]);
141             stringWriter.append(set[num2]);
142             stringWriter.append(set[num3]);
143             stringWriter.append(set[num4]);
144 
145             offset += step;
146         }
147         if (app == 1) {
148             stringWriter.append(blank);
149         }
150         if (app == 2) {
151             stringWriter.append(blank);
152             stringWriter.append(blank);
153         }
154         return stringWriter.toString();
155     }
156 }

结果可以作为url组件, 并且保持相同于源字节数组大小关系 (按从0偏移处比较, 鸡蛋大头开始, 不知道喜欢大头的多还是小头的多)。

原文地址:https://www.cnblogs.com/silvestris/p/2942843.html