<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>The Kitchen in the Zoo - encoding tag</title>
  <link>http://blog.maxant.co.uk:80/pebble/tags/encoding/</link>
  <description>&lt;small&gt;A blog where Ant writes about anything he finds interesting! &lt;a href=&#039;http://www.linkedin.com/in/maxant&#039;&gt;&lt;font color=&#039;white&#039;&gt;Who is Ant?&lt;/font&gt;&lt;/a&gt;      &lt;a href=&#039;/pebble/pages/copyright.html&#039;&gt;&lt;font color=&#039;white&#039;&gt;Copyright 2005-2012 Ant Kutschera&lt;/font&gt;&lt;/a&gt;&lt;/small&gt;</description>
  <language>en</language>
  <copyright>Ant Kutschera</copyright>
  <lastBuildDate>Thu, 10 May 2012 20:07:00 GMT</lastBuildDate>
  <generator>Pebble (http://pebble.sourceforge.net)</generator>
  <docs>http://backend.userland.com/rss</docs>
  
  
  <item>
    <title>Base X Encoding</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html</link>
    
      
        <description>
          &lt;p&gt;Ever needed to shorten a number so that its easier to remember? Or provide someone with a temporary PIN which is short enough to remember, but long enough to pretty much ensure it wont be randomly guessed by someone else? Converting a binary number into a hexadecimal is exactly the process used in such cases. But hexadecimal only has 16 characters in its &amp;quot;dictionary&amp;quot;. Base64 is the next step up, with a bigger dictionary containing all alphanumerics (upper and lower case) as well as &amp;quot;/&amp;quot; and &amp;quot;+&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
I need a solution which didn&#039;t contain certain characters. For example, its easy to mix up an O with a 0. Or an I,l and a 1. I wanted a solution whereby I could encode a number, but using my own definition of the dictionary. So I built just such a solution. You can see the source code below. It contains a main method which runs a simple test, the output of which is:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Original: 123456789012345678901234567890&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; encoded: 2aYls9bkamJJSwhr0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; decoded: 123456789012345678901234567890&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Passed! decoded value is the same as the original.&lt;br /&gt;
&lt;br /&gt;
As you can see, the encoded version is only half as long as the input. Using an 89 character dictionary, it gets even shorter:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; encoded: &amp;quot;9Kgbz])M.w8KgK&lt;br /&gt;
&lt;br /&gt;
The implementation uses the BigInteger class from Java, so you can encode REALLY big numbers. My phone number is now only 5 characters long and really easy to remember:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; rDm3T&lt;/p&gt;
&lt;hr size=&#034;2&#034; width=&#034;100%&#034; /&gt;
&lt;div style=&#034;border: thin none ; overflow: auto; width: 525px; height: 300px; background-color: rgb(255, 255, 255);&#034;&gt;
&lt;pre&gt;
/*  
 * Copyright (c) 2010 Ant Kutschera, maxant
 * 
 * The code below is free software: you can redistribute it and/or modify
 * it under the terms of the Lesser GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * The code in this file is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Lesser GNU General Public License for more details.
 * You should have received a copy of the Lesser GNU General Public License
 * along with Foobar.  If not, see http://www.gnu.org/licenses/.
 */

package uk.co.maxant.util;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * allows you to convert a whole number into a compacted representation of that number,
 * based upon the dictionary you provide. very similar to base64 encoding, or indeed hex
 * encoding.
 */
public class BaseX {

	/**
	 * contains hexadecimals 0-F only.
	 */
	public static final char[] DICTIONARY_16 = 
		new char[]{&#039;0&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;,&#039;E&#039;,&#039;F&#039;};

	/**
	 * contains only alphanumerics, in capitals and excludes letters/numbers which can be confused,
	 * eg. 0 and O or L and I and 1.
	 */
	public static final char[] DICTIONARY_32 = 
		new char[]{&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;,&#039;E&#039;,&#039;F&#039;,&#039;G&#039;,&#039;H&#039;,&#039;J&#039;,&#039;K&#039;,&#039;M&#039;,&#039;N&#039;,&#039;P&#039;,&#039;Q&#039;,&#039;R&#039;,&#039;S&#039;,&#039;T&#039;,&#039;U&#039;,&#039;V&#039;,&#039;W&#039;,&#039;X&#039;,&#039;Y&#039;,&#039;Z&#039;};

	/**
	 * contains only alphanumerics, including both capitals and smalls.
	 */
	public static final char[] DICTIONARY_62 = 
		new char[]{&#039;0&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;,&#039;E&#039;,&#039;F&#039;,&#039;G&#039;,&#039;H&#039;,&#039;I&#039;,&#039;J&#039;,&#039;K&#039;,&#039;L&#039;,&#039;M&#039;,&#039;N&#039;,&#039;O&#039;,&#039;P&#039;,&#039;Q&#039;,&#039;R&#039;,&#039;S&#039;,&#039;T&#039;,&#039;U&#039;,&#039;V&#039;,&#039;W&#039;,&#039;X&#039;,&#039;Y&#039;,&#039;Z&#039;,&#039;a&#039;,&#039;b&#039;,&#039;c&#039;,&#039;d&#039;,&#039;e&#039;,&#039;f&#039;,&#039;g&#039;,&#039;h&#039;,&#039;i&#039;,&#039;j&#039;,&#039;k&#039;,&#039;l&#039;,&#039;m&#039;,&#039;n&#039;,&#039;o&#039;,&#039;p&#039;,&#039;q&#039;,&#039;r&#039;,&#039;s&#039;,&#039;t&#039;,&#039;u&#039;,&#039;v&#039;,&#039;w&#039;,&#039;x&#039;,&#039;y&#039;,&#039;z&#039;};

	/**
	 * contains alphanumerics, including both capitals and smalls, and the following special chars:
	 * +&amp;quot;@*#%&amp;amp;/|()=?&#039;~[!]{}-_:.,; (you might not be able to read all those using a browser!
	 */
	public static final char[] DICTIONARY_89 = 
		new char[]{&#039;0&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;,&#039;E&#039;,&#039;F&#039;,&#039;G&#039;,&#039;H&#039;,&#039;I&#039;,&#039;J&#039;,&#039;K&#039;,&#039;L&#039;,&#039;M&#039;,&#039;N&#039;,&#039;O&#039;,&#039;P&#039;,&#039;Q&#039;,&#039;R&#039;,&#039;S&#039;,&#039;T&#039;,&#039;U&#039;,&#039;V&#039;,&#039;W&#039;,&#039;X&#039;,&#039;Y&#039;,&#039;Z&#039;,&#039;a&#039;,&#039;b&#039;,&#039;c&#039;,&#039;d&#039;,&#039;e&#039;,&#039;f&#039;,&#039;g&#039;,&#039;h&#039;,&#039;i&#039;,&#039;j&#039;,&#039;k&#039;,&#039;l&#039;,&#039;m&#039;,&#039;n&#039;,&#039;o&#039;,&#039;p&#039;,&#039;q&#039;,&#039;r&#039;,&#039;s&#039;,&#039;t&#039;,&#039;u&#039;,&#039;v&#039;,&#039;w&#039;,&#039;x&#039;,&#039;y&#039;,&#039;z&#039;,&#039;+&#039;,&#039;&amp;quot;&#039;,&#039;@&#039;,&#039;*&#039;,&#039;#&#039;,&#039;%&#039;,&#039;&amp;amp;&#039;,&#039;/&#039;,&#039;|&#039;,&#039;(&#039;,&#039;)&#039;,&#039;=&#039;,&#039;?&#039;,&#039;~&#039;,&#039;[&#039;,&#039;]&#039;,&#039;{&#039;,&#039;}&#039;,&#039;$&#039;,&#039;-&#039;,&#039;_&#039;,&#039;.&#039;,&#039;:&#039;,&#039;,&#039;,&#039;;&#039;,&#039;&amp;lt;&#039;,&#039;&amp;gt;&#039;};
	
	protected char[] dictionary;

	/**
	 * create an encoder with the given dictionary.
	 * 
	 * @param dictionary the dictionary to use when encoding and decoding.
	 */
	public BaseX(char[] dictionary){
		this.dictionary = dictionary;
	}
	
	/**
	 * creates an encoder with the {@link #DICTIONARY_62} dictionary.
	 *  
	 * @param dictionary the dictionary to use when encoding and decoding.
	 */
	public BaseX(){
		this.dictionary = DICTIONARY_62;
	}
	
	/**
	 * tester method.
	 */
	public static void main(String[] args) {
		String original = &amp;quot;123456789012345678901234567890&amp;quot;;
		System.out.println(&amp;quot;Original: &amp;quot; + original);
		BaseX bx = new BaseX(DICTIONARY_62);
		String encoded = bx.encode(new BigInteger(original));
		System.out.println(&amp;quot;encoded: &amp;quot; + encoded);
		BigInteger decoded = bx.decode(encoded);
		System.out.println(&amp;quot;decoded: &amp;quot; + decoded);
		if(original.equals(decoded.toString())){
			System.out.println(&amp;quot;Passed! decoded value is the same as the original.&amp;quot;);
		}else{
			System.err.println(&amp;quot;FAILED! decoded value is NOT the same as the original!!&amp;quot;);
		}
	}

	/**
	 * encodes the given string into the base of the dictionary provided in the constructor.
	 * @param value the number to encode.
	 * @return the encoded string.
	 */
	public String encode(BigInteger value) {
		
		List&amp;lt;Character&amp;gt; result = new ArrayList&amp;lt;Character&amp;gt;();
		BigInteger base = new BigInteger(&amp;quot;&amp;quot; + dictionary.length);
		int exponent = 1;
		BigInteger remaining = value;
		while(true){
			BigInteger a = base.pow(exponent); //16^1 = 16
			BigInteger b = remaining.mod(a); //119 % 16 = 7 | 112 % 256 = 112
			BigInteger c = base.pow(exponent - 1);
			BigInteger d = b.divide(c);
			
			//if d &amp;gt; dictionary.length, we have a problem. but BigInteger doesnt have
			//a greater than method :-(  hope for the best. theoretically, d is always 
			//an index of the dictionary!
			result.add(dictionary[d.intValue()]);
			remaining = remaining.subtract(b); //119 - 7 = 112 | 112 - 112 = 0

			//finished?
			if(remaining.equals(BigInteger.ZERO)){
				break;
			}

			exponent++;
		}

		//need to reverse it, since the start of the list contains the least significant values
		StringBuffer sb = new StringBuffer();
		for(int i = result.size()-1; i &amp;gt;= 0; i--){
			sb.append(result.get(i));
		}
		return sb.toString();
	}
	
	/**
	 * decodes the given string from the base of the dictionary provided in the constructor.
	 * @param str the string to decode.
	 * @return the decoded number.
	 */
	public BigInteger decode(String str) {

		//reverse it, coz its already reversed!
		char[] chars = new char[str.length()];
		str.getChars(0, str.length(), chars, 0);

		char[] chars2 = new char[str.length()];
		int i = chars2.length -1;
		for(char c : chars){
			chars2[i--] = c;
		}

		//for efficiency, make a map
		Map&amp;lt;Character, BigInteger&amp;gt; dictMap = new HashMap&amp;lt;Character, BigInteger&amp;gt;();
		int j = 0;
		for(char c : dictionary){
			dictMap.put(c, new BigInteger(&amp;quot;&amp;quot; + j++));
		}

		BigInteger bi = BigInteger.ZERO;
		BigInteger base = new BigInteger(&amp;quot;&amp;quot; + dictionary.length);
		int exponent = 0;
		for(char c : chars2){
			BigInteger a = dictMap.get(c);
			BigInteger b = base.pow(exponent).multiply(a);
			bi = bi.add(new BigInteger(&amp;quot;&amp;quot; + b));
			exponent++;
		}

		return bi;
		
	}
	
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;hr size=&#034;2&#034; width=&#034;100%&#034; /&gt;
&lt;p&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
Copyright (c)2010 Dr Ant Kutschera&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;t=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;title=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html&amp;amp;t=Base+X+Encoding&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2010/02/02/1265138340000.html</guid>
    <pubDate>Tue, 02 Feb 2010 19:19:00 GMT</pubDate>
  </item>
  
  </channel>
</rss>

