View Javadoc

1   /*
2    * Copyright 2000 - 2010 Ivan Khalopik. All Rights Reserved.
3    */
4   
5   package org.greatage.util;
6   
7   import java.security.MessageDigest;
8   import java.security.NoSuchAlgorithmException;
9   
10  /**
11   * This class represents utility for encoding data.
12   *
13   * @author Ivan Khalopik
14   * @since 1.0
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  	 * Encodes binary data using specified message digest algorithm.
30  	 *
31  	 * @param data	  binary data
32  	 * @param algorithm message digest algorithm
33  	 * @return encoded binary data
34  	 * @throws IllegalArgumentException if specified algorithm not found
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  	 * Encodes binary data using Base64 algorithm.
47  	 *
48  	 * @param data binary data
49  	 * @return encoded binary data
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  }