01: package com.vividsolutions.jump.util;
02:
03: import java.util.*;
04:
05: /**
06: * Provides a simple encyrption/decryption mechanism for ASCII string values.
07: * The algorithm does not provide strong encryption, but serves
08: * as a way of obfuscating the value of short strings (such as passwords).
09: * The code symbol set is drawn from the set of printable ASCII symbols.
10: * The encrypted strings are longer than the clear text (roughly double in length).
11: * A random element is used, so that different encryptions of the same clear
12: * text will result in different encodings.
13: */
14: public class SimpleStringEncrypter {
15: private static final String INVALID_CODE_STRING_MSG = "Invalid code string";
16:
17: private static String codeSymbols = "ABCDEFGHIJKLMNOP"
18: + "abcdefghijklmnop" + "QRSTUVWXYZ012345"
19: + "qrstuvwxyz6789@$";
20:
21: /**
22: * Creates a new encrypter
23: */
24: public SimpleStringEncrypter() {
25: }
26:
27: /**
28: * Encrypts a string.
29: *
30: * @param clearText the string to encrypt
31: * @return the encryted code
32: */
33: public String encrypt(String clearText) {
34: char[] code = new char[clearText.length() * 2];
35: for (int i = 0; i < clearText.length(); i++) {
36: char c = clearText.charAt(i);
37: setEncryptedSymbol(c, code, 2 * i);
38: }
39: return new String(code);
40: }
41:
42: public void setEncryptedSymbol(char c, char[] code, int i) {
43: int charVal = c;
44: int nibble0 = charVal & 0xf;
45: int nibble1 = charVal >> 4;
46:
47: code[i] = encodeNibble(nibble0);
48: code[i + 1] = encodeNibble(nibble1);
49: }
50:
51: private char encodeNibble(int val) {
52: int random4 = (int) (4 * Math.random());
53: int randomOffset = 16 * random4;
54: return codeSymbols.charAt(val + randomOffset);
55: }
56:
57: /**
58: * Decrypts a code string.
59: *
60: * @param codeText the code to decrypt
61: * @return the clear text for the code
62: *
63: * @throws IllegalArgumentException if the code string is invalid
64: */
65: public String decrypt(String codeText) {
66: if (codeText.length() % 2 != 0)
67: throw new IllegalArgumentException(INVALID_CODE_STRING_MSG);
68: char[] clear = new char[codeText.length() / 2];
69: for (int i = 0; i < codeText.length() / 2; i++) {
70: char symbol0 = codeText.charAt(2 * i);
71: char symbol1 = codeText.charAt(2 * i + 1);
72: clear[i] = decryptedChar(symbol0, symbol1);
73: }
74: return new String(clear);
75: }
76:
77: private char decryptedChar(char symbol0, char symbol1) {
78: int nibble0 = decodeNibble(symbol0);
79: int nibble1 = decodeNibble(symbol1);
80: int charVal = nibble1 << 4 | nibble0;
81: return (char) charVal;
82: }
83:
84: private int decodeNibble(int symbolValue) {
85: int nibbleValue = codeSymbols.indexOf(symbolValue);
86: if (nibbleValue < 0)
87: throw new IllegalArgumentException(INVALID_CODE_STRING_MSG);
88: return nibbleValue % 16;
89: }
90:
91: }
|