1
2
3
4
5 package org.greatage.util;
6
7 import java.security.MessageDigest;
8 import java.security.NoSuchAlgorithmException;
9
10
11
12
13
14
15
16 public abstract class EncodeUtils {
17 private static final byte BASE64_NULL = '=';
18
19 private static final byte BASE64_DICTIONARY[] = {
20 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
21 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
22 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
23 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
24 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
25 };
26 private static final int BASE64_MASK = 0x3f;
27
28
29
30
31
32
33
34
35
36 public static byte[] encode(final byte[] data, final String algorithm) {
37 try {
38 final MessageDigest digest = MessageDigest.getInstance(algorithm);
39 return digest.digest(data);
40 } catch (NoSuchAlgorithmException e) {
41 throw new IllegalArgumentException(String.format("Unknown digest algorithm: '%s'", algorithm));
42 }
43 }
44
45
46
47
48
49
50
51 public static byte[] encodeBase64(final byte[] data) {
52 final int tripleCount = data.length / 3;
53 final int resultLength = data.length % 3 == 0 ? 4 * tripleCount : 4 * (tripleCount + 1);
54 final byte[] result = new byte[resultLength];
55
56 int dataCursor = 0, resultCursor = 0;
57 for (int i = 0; i < tripleCount; i++) {
58 final byte byte0 = data[dataCursor++];
59 final byte byte1 = data[dataCursor++];
60 final byte byte2 = data[dataCursor++];
61 result[resultCursor++] = BASE64_DICTIONARY[byte0 >> 2];
62 result[resultCursor++] = BASE64_DICTIONARY[(byte0 << 4) & BASE64_MASK | (byte1 >> 4)];
63 result[resultCursor++] = BASE64_DICTIONARY[(byte1 << 2) & BASE64_MASK | (byte2 >> 6)];
64 result[resultCursor++] = BASE64_DICTIONARY[byte2 & BASE64_MASK];
65 }
66
67 switch (data.length - dataCursor) {
68 case 1:
69 final byte b = data[dataCursor];
70 result[resultCursor++] = BASE64_DICTIONARY[b >> 2];
71 result[resultCursor++] = BASE64_DICTIONARY[(b << 4) & BASE64_MASK];
72 result[resultCursor++] = BASE64_NULL;
73 result[resultCursor] = BASE64_NULL;
74 break;
75 case 2:
76 final byte b0 = data[dataCursor++];
77 final byte b1 = data[dataCursor];
78 result[resultCursor++] = BASE64_DICTIONARY[b0 >> 2];
79 result[resultCursor++] = BASE64_DICTIONARY[(b0 << 4) & BASE64_MASK | (b1 >> 4)];
80 result[resultCursor++] = BASE64_DICTIONARY[(b1 << 2) & BASE64_MASK];
81 result[resultCursor] = BASE64_NULL;
82 break;
83 }
84 return result;
85 }
86 }