Advertisement
Guest User

alphabet

a guest
May 19th, 2010
538
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.95 KB | None | 0 0
  1. public class AlphabetHelper {
  2.  
  3.     private static final char[] PRIVATE_ALPHABET;
  4.     private static final char[] PUBLIC_ALPHABET;
  5.  
  6.     // initialize alphabets
  7.     static {
  8.         final StringBuilder privateBuilder = new StringBuilder();
  9.         final StringBuilder publicBuilder = new StringBuilder();
  10.  
  11.         // digits
  12.         privateBuilder.append("0123456789");
  13.         publicBuilder.append("0123456789");
  14.  
  15.         // upper case
  16.         privateBuilder.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  17.         publicBuilder.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  18.  
  19.         // underscore
  20.         privateBuilder.append('_');
  21.  
  22.         // lower case
  23.         publicBuilder.append("abcdefghijklmnopqrstuvwxyz");
  24.  
  25.         int offset;
  26.  
  27.         final List<Character> privateList = Arrays.asList(
  28.         // convert Character[] to List<Character>
  29.                 ArrayUtils.toObject(
  30.                 // convert char[] to Character[]
  31.                         privateBuilder.toString().toCharArray()));
  32.         Collections.shuffle(privateList); // shuffle the list
  33.  
  34.         PRIVATE_ALPHABET = new char[privateList.size()];
  35.         offset = 0;
  36.         for (final Character character : privateList) {
  37.             PRIVATE_ALPHABET[offset++] = character.charValue();
  38.         }
  39.  
  40.         final List<Character> publicList = Arrays.asList(
  41.         // convert Character[] to List<Character>
  42.                 ArrayUtils.toObject(
  43.                 // convert char[] to Character[]
  44.                         publicBuilder.toString().toCharArray()));
  45.         Collections.shuffle(publicList); // shuffle the list
  46.  
  47.         PUBLIC_ALPHABET = new char[publicList.size()];
  48.         offset = 0;
  49.         for (final Character character : publicList) {
  50.             PUBLIC_ALPHABET[offset++] = character.charValue();
  51.         }
  52.  
  53.     }
  54.  
  55.     private static final Logger LOG = LoggerFactory
  56.             .getLogger(AlphabetHelper.class);
  57.  
  58.     public static String decode(final String encodedText) {
  59.         if (!verify(encodedText, PUBLIC_ALPHABET)) {
  60.             return null;
  61.         }
  62.         final int length = ArrayUtils.indexOf(PUBLIC_ALPHABET, encodedText
  63.                 .charAt(0));
  64.         final BigInteger mapped = getTextAsNumber(encodedText.substring(1),
  65.                 PUBLIC_ALPHABET);
  66.         return StringUtils.leftPad(getNumberAsText(mapped, PRIVATE_ALPHABET),
  67.                 length, PRIVATE_ALPHABET[0]);
  68.     }
  69.  
  70.     public static String encode(final String clearText) {
  71.         if (!verify(clearText, PRIVATE_ALPHABET)) {
  72.             return null;
  73.         }
  74.         final BigInteger mapped = getTextAsNumber(clearText, PRIVATE_ALPHABET);
  75.         return PUBLIC_ALPHABET[clearText.length()]
  76.                 + getNumberAsText(mapped, PUBLIC_ALPHABET);
  77.     }
  78.  
  79.     private static String getNumberAsText(final BigInteger number,
  80.             final char[] alphabet) {
  81.         final StringBuilder builder = new StringBuilder();
  82.         final BigInteger radix = BigInteger.valueOf(alphabet.length);
  83.         BigInteger snapShot = number;
  84.         while (snapShot.compareTo(BigInteger.ZERO) > 0) {
  85.             final BigInteger[] tuple = snapShot.divideAndRemainder(radix);
  86.             builder.append(alphabet[(int) tuple[1].longValue()]);
  87.             snapShot = tuple[0];
  88.         }
  89.         final String value = builder.reverse().toString();
  90.         LOG.info("Decoded string {} from number {}", value, number);
  91.         return value;
  92.     }
  93.  
  94.     private static BigInteger getTextAsNumber(final String charString,
  95.             final char[] alphabet) {
  96.  
  97.         BigInteger value = BigInteger.ZERO;
  98.         final char[] chars = charString.toCharArray();
  99.         final int radix = alphabet.length;
  100.         final int wordLength = chars.length;
  101.         for (int i = 0; i < wordLength; i++) {
  102.             final char c = chars[wordLength - (i + 1)];
  103.             value = value.add(//
  104.                     BigInteger.valueOf(radix).pow(i)
  105.                             .multiply(
  106.                                     BigInteger.valueOf(ArrayUtils.indexOf(
  107.                                             alphabet, c))));
  108.         }
  109.         LOG.info("Decoded value {} from string {}", value, charString);
  110.         return value;
  111.     }
  112.  
  113.     private static boolean verify(final String candidate,
  114.             final char[] publicAlphabet) {
  115.         boolean result;
  116.         if (candidate == null) {
  117.             result = false;
  118.         } else {
  119.             result = true;
  120.             for (final char ch : candidate.toCharArray()) {
  121.                 if (!ArrayUtils.contains(publicAlphabet, ch)) {
  122.                     result = false;
  123.                     break;
  124.                 }
  125.             }
  126.         }
  127.         return result;
  128.     }
  129.  
  130. }
  131.  
  132.  
  133.  
  134. public class AlphabetHelperTest {
  135.  
  136.     private Random random;
  137.     private char[] alphabet;
  138.  
  139.     private static final Logger LOG = LoggerFactory
  140.             .getLogger(AlphabetHelperTest.class);
  141.  
  142.     @Before
  143.     public void setup() {
  144.         this.random = new Random();
  145.         this.alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".toCharArray();
  146.     }
  147.  
  148.     @Test
  149.     public void testEncodeDecode() {
  150.  
  151.         for (int i = 0; i < 20; i++) {
  152.             final String clearText =  this.getRandomString();
  153.             // "FRTV0VN3IE7LA1U"; <-- This string always fails!!!
  154.             final String encodedString = AlphabetHelper.encode(clearText);
  155.             final String decodedString = AlphabetHelper.decode(encodedString);
  156.             LOG.info("Original: {}, encoded: {}, decoded: {}", new String[] {
  157.                     clearText, encodedString, decodedString });
  158.             assertEquals(decodedString, clearText);
  159.         }
  160.  
  161.     }
  162.  
  163.     private String getRandomString() {
  164.         final int stringSize = this.random.nextInt(10) + 6;
  165.         final StringBuilder sb = new StringBuilder();
  166.         for (int ct = 0; ct < stringSize; ct++) {
  167.             sb.append(this.alphabet[this.random.nextInt(this.alphabet.length)]);
  168.         }
  169.         return sb.toString();
  170.     }
  171.  
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement