base64的URL传输

众所周知标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号如果在存入数据库时还需要再进行转换。下面提供一个适合URL的改进版本。

调用方法:

1
2
3
4
5
6
7
8
9
public static String base64Encode(String str) {
	byte[] bytes = UrlBase64.encode(str.getBytes());
	return new String(bytes);
}
 
public static String base64Decode(String str) {
	byte[] bytes = UrlBase64.decode(str.getBytes());
	return new String(bytes);
}

具体的使用方法,例如我的action_19参数的值需要用加密:

1
2
String url = "servlet?action_19="+Tools.base64Encode(num);
url = java.net.URLEncoder.encode(url);

之后访问servlet得到action_19解密即可~这其实也间接解决了GET中含有中文乱码的问题(当然这不是最好的GET中文乱码解决方法)。

以下为具体的类:

UrlBase64Encoder.java

1
2
3
4
5
6
7
8
9
10
11
package com.rizon.apollo.xnjk.util;
 
public class UrlBase64Encoder extends Base64Encoder {
 
	public UrlBase64Encoder() {
		encodingTable[encodingTable.length - 2] = 45;
		encodingTable[encodingTable.length - 1] = 95;
		padding = 46;
		initialiseDecodingTable();
	}
}

UrlBase64.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.rizon.apollo.xnjk.util;
 
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
 
//Referenced classes of package org.bouncycastle.util.encoders:
//         UrlBase64Encoder, Encoder
 
public class UrlBase64 {
 
	private static final Encoder encoder = new UrlBase64Encoder();
 
	public UrlBase64() {
	}
 
	public static byte[] encode(byte abyte0[]) {
		ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
		try {
			encoder.encode(abyte0, 0, abyte0.length, bytearrayoutputstream);
		} catch (IOException ioexception) {
			throw new RuntimeException((new StringBuilder()).append(
					"exception encoding URL safe base64 string: ").append(
					ioexception).toString());
		}
		return bytearrayoutputstream.toByteArray();
	}
 
	public static int encode(byte abyte0[], OutputStream outputstream)
			throws IOException {
		return encoder.encode(abyte0, 0, abyte0.length, outputstream);
	}
 
	public static byte[] decode(byte abyte0[]) {
		ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
		try {
			encoder.decode(abyte0, 0, abyte0.length, bytearrayoutputstream);
		} catch (IOException ioexception) {
			throw new RuntimeException((new StringBuilder()).append(
					"exception decoding URL safe base64 string: ").append(
					ioexception).toString());
		}
		return bytearrayoutputstream.toByteArray();
	}
 
	public static int decode(byte abyte0[], OutputStream outputstream)
			throws IOException {
		return encoder.decode(abyte0, 0, abyte0.length, outputstream);
	}
 
	public static byte[] decode(String s) {
		ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
		try {
			encoder.decode(s, bytearrayoutputstream);
		} catch (IOException ioexception) {
			throw new RuntimeException((new StringBuilder()).append(
					"exception decoding URL safe base64 string: ").append(
					ioexception).toString());
		}
		return bytearrayoutputstream.toByteArray();
	}
 
	public static int decode(String s, OutputStream outputstream)
			throws IOException {
		return encoder.decode(s, outputstream);
	}
 
}

Encoder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.rizon.apollo.xnjk.util;
 
import java.io.IOException;
import java.io.OutputStream;
 
public interface Encoder {
 
	public abstract int encode(byte abyte0[], int i, int j,
			OutputStream outputstream) throws IOException;
 
	public abstract int decode(byte abyte0[], int i, int j,
			OutputStream outputstream) throws IOException;
 
	public abstract int decode(String s, OutputStream outputstream)
			throws IOException;
}

Base64Encoder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package com.rizon.apollo.xnjk.util;
 
import java.io.IOException;
import java.io.OutputStream;
 
// Referenced classes of package org.bouncycastle.util.encoders:
//            Encoder
 
public class Base64Encoder implements Encoder {
 
	protected final byte encodingTable[] = { 65, 66, 67, 68, 69, 70, 71, 72,
			73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
			90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
			110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
			48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 };
	protected byte padding;
	protected final byte decodingTable[] = new byte[128];
 
	protected void initialiseDecodingTable() {
		for (int i = 0; i < encodingTable.length; i++) {
			decodingTable[encodingTable[i]] = (byte) i;
		}
 
	}
 
	public Base64Encoder() {
		padding = 61;
		initialiseDecodingTable();
	}
 
	public int encode(byte abyte0[], int i, int j, OutputStream outputstream)
			throws IOException {
		int k = j % 3;
		int l = j - k;
		for (int l1 = i; l1 < i + l; l1 += 3) {
			int i1 = abyte0[l1] & 0xff;
			int j1 = abyte0[l1 + 1] & 0xff;
			int k1 = abyte0[l1 + 2] & 0xff;
			outputstream.write(encodingTable[i1 >>> 2 & 0x3f]);
			outputstream.write(encodingTable[(i1 << 4 | j1 >>> 4) & 0x3f]);
			outputstream.write(encodingTable[(j1 << 2 | k1 >>> 6) & 0x3f]);
			outputstream.write(encodingTable[k1 & 0x3f]);
		}
 
		switch (k) {
		case 1: // '\001'
			int j3 = abyte0[i + l] & 0xff;
			int i2 = j3 >>> 2 & 0x3f;
			int k2 = j3 << 4 & 0x3f;
			outputstream.write(encodingTable[i2]);
			outputstream.write(encodingTable[k2]);
			outputstream.write(padding);
			outputstream.write(padding);
			break;
 
		case 2: // '\002'
			int k3 = abyte0[i + l] & 0xff;
			int l3 = abyte0[i + l + 1] & 0xff;
			int j2 = k3 >>> 2 & 0x3f;
			int l2 = (k3 << 4 | l3 >>> 4) & 0x3f;
			int i3 = l3 << 2 & 0x3f;
			outputstream.write(encodingTable[j2]);
			outputstream.write(encodingTable[l2]);
			outputstream.write(encodingTable[i3]);
			outputstream.write(padding);
			break;
		}
		return (l / 3) * 4 + (k != 0 ? 4 : 0);
	}
 
	private boolean ignore(char c) {
		return c == '\n' || c == '\r' || c == '\t' || c == ' ';
	}
 
	public int decode(byte abyte0[], int i, int j, OutputStream outputstream)
			throws IOException {
		int k = 0;
		int l;
		for (l = i + j; l > i && ignore((char) abyte0[l - 1]); l--) {
		}
		int i1 = i;
		int j1 = l - 4;
		for (i1 = nextI(abyte0, i1, j1); i1 < j1; i1 = nextI(abyte0, i1, j1)) {
			byte byte0 = decodingTable[abyte0[i1++]];
			i1 = nextI(abyte0, i1, j1);
			byte byte1 = decodingTable[abyte0[i1++]];
			i1 = nextI(abyte0, i1, j1);
			byte byte2 = decodingTable[abyte0[i1++]];
			i1 = nextI(abyte0, i1, j1);
			byte byte3 = decodingTable[abyte0[i1++]];
			outputstream.write(byte0 << 2 | byte1 >> 4);
			outputstream.write(byte1 << 4 | byte2 >> 2);
			outputstream.write(byte2 << 6 | byte3);
			k += 3;
		}
 
		k += decodeLastBlock(outputstream, (char) abyte0[l - 4],
				(char) abyte0[l - 3], (char) abyte0[l - 2],
				(char) abyte0[l - 1]);
		return k;
	}
 
	private int nextI(byte abyte0[], int i, int j) {
		for (; i < j && ignore((char) abyte0[i]); i++) {
		}
		return i;
	}
 
	public int decode(String s, OutputStream outputstream) throws IOException {
		int i = 0;
		int j;
		for (j = s.length(); j > 0 && ignore(s.charAt(j - 1)); j--) {
		}
		int k = 0;
		int l = j - 4;
		for (k = nextI(s, k, l); k < l; k = nextI(s, k, l)) {
			byte byte0 = decodingTable[s.charAt(k++)];
			k = nextI(s, k, l);
			byte byte1 = decodingTable[s.charAt(k++)];
			k = nextI(s, k, l);
			byte byte2 = decodingTable[s.charAt(k++)];
			k = nextI(s, k, l);
			byte byte3 = decodingTable[s.charAt(k++)];
			outputstream.write(byte0 << 2 | byte1 >> 4);
			outputstream.write(byte1 << 4 | byte2 >> 2);
			outputstream.write(byte2 << 6 | byte3);
			i += 3;
		}
 
		i += decodeLastBlock(outputstream, s.charAt(j - 4), s.charAt(j - 3), s
				.charAt(j - 2), s.charAt(j - 1));
		return i;
	}
 
 
	private int decodeLastBlock(OutputStream outputstream, char c, char c1,
			char c2, char c3) throws IOException {
		if (c2 == padding) {
			byte byte0 = decodingTable[c];
			byte byte3 = decodingTable[c1];
			outputstream.write(byte0 << 2 | byte3 >> 4);
			return 1;
		}
		if (c3 == padding) {
			byte byte1 = decodingTable[c];
			byte byte4 = decodingTable[c1];
			byte byte6 = decodingTable[c2];
			outputstream.write(byte1 << 2 | byte4 >> 4);
			outputstream.write(byte4 << 4 | byte6 >> 2);
			return 2;
		} else {
			byte byte2 = decodingTable[c];
			byte byte5 = decodingTable[c1];
			byte byte7 = decodingTable[c2];
			byte byte8 = decodingTable[c3];
			outputstream.write(byte2 << 2 | byte5 >> 4);
			outputstream.write(byte5 << 4 | byte7 >> 2);
			outputstream.write(byte7 << 6 | byte8);
			return 3;
		}
	}
 
	private int nextI(String s, int i, int j) {
		for (; i < j && ignore(s.charAt(i)); i++) {
		}
		return i;
	}
}

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">