Wednesday 11 April 2012

Base96 Decoding

We saw in the last post that the command chr() converts a value to it's ASCII Character equivalent, so before we dive in to the decode function, let's cover it's opposite command asc() .

This has a slighter more sensible name, asc is short for ASCII, which incidentally for those interested in these things is an acronym for the American Standard Code for Information Interchange.

There are plenty of references on the web which list the codes and their character equivalents such as http://www.asciitable.com/ and http://en.wikipedia.org/wiki/ASCII.

Windows also has a tool called Character Map which shows the characters from 32 upwards
When you select a character, at the bottom it shows it's value in hexadecimal (base 16).  However this is technically not ASCII, hence the exclamation mark is shown as U+0021.

Anyway back to the command asc() which converts a string character back to it's ASCII value, so space would be converted to 32, "A" would be converted to 65 and so on.

This is used in the function which decodes the string, simply doing the reverse of what we did to encode it.
  • get the ASCII value of the two characters
  • subtract 32
  • multiply the high value by 96 and add the low value
The result is then returned as a value.

function Base96Decode( thisString$ )
   thisLen = len(thisString$)
   if thisLen = 0
      thisValue = 0
   else
      if thisLen = 1 then thisString$ = " " + thisString$
      highValue = asc( left( thisString$ , 1 ) ) - 32
      lowValue = asc( mid( thisString$ , 2, 1 ) ) - 32
      thisValue = highValue * 96 + lowValue
   endif
endfunction thisValue

At the start of the function - which is a long hand version to keep it readable - we get the length of the string using the command len() which indicates how many characters are in a string. The result is stored in thisLen.  We need it to be 2 characters to decode properly.

If the length is zero, we simply return zero to thisValue.

Otherwise, we check if the length is 1, in which case we add a space to the start and continue.

The left() command is used to retrieve the left most characters from a string, the value 1 indicates we want 1 character.

The mid() command is used to retrieve characters from the middle of the string, the 2 indicates we start at position 2, the 1 indicates we want 1 character.

In both cases, then get the ascii value with the asc() command, subtract 32 from the result and store it in the variables.

The high value is multipled by 96 and added to the low value and the result stored in thisValue, which is returned from the function.

To test the this, we modify the lines we used in the last post to

for i=0 to 9
   thisCode$ = Base96Encode( i )
   thisDecode = Base96Decode( thisCode$ )
   s$ = chr(34) + thisCode$ + chr(34)
   s$ = s$ + " = " + str( thisDecode )
   print( str(i) + " = " + s$ )
next i
for i=95 to 104
   thisCode$ = Base96Encode( i )
   thisDecode = Base96Decode( thisCode$ )
   s$ = chr(34) + thisCode$ + chr(34)
   s$ = s$ + " = " + str( thisDecode )
   print( str(i) + " = " + s$ )
next i

This time, we get the encoded string at the start and store it in a string called thisCode$, we then pass this to the decode function and store the result in thisDecode.

Again we build the string s$, but this time in 2 parts.

The first part uses the chr(34)'s as before with thisCode$ in the middle and now we have a second part which joins onto the existing string an equals sign and the string version of the decoded value in thisDecode.

The decoded value should be the same as the one we started with (i), so the number at the start of the line and at the end of the line should be the same.
Which (when we move the sprite out of the way) we can see they are.

No comments:

Post a Comment