Monday, 24 September 2012

Not what I was intending to do today

G'day:
I'm back in a cold, wet London after a rather sunny (if quite cool) weekend in Ireland.  And I have a day off work today to recharge my batteries a bit after all the planes, trains & automobiles in the last coupla days.

I was going to write an article "not really about closures" today, but I got sidetracked whilst looking at StackOverflow, and ended up doing something else instead.  It's just a function to convert a number from one arbitrary base to another arbitrary base, and I pinched the algorithm from someone else, but I quite like it so I'm gonna share it here.  And I'll submit it to CFLib too, as  - surprisingly - they do not already seem to have a function to do this.  Weird: I thought everyone has written one of these at some point or another (I know it's about the third time I have written a variation on this theme).


The original StackOverflow question was this one: someone wanting a unique ID but not one that was as long as a UUID.  I was going to suggest they converted the UUID to base-62 (0-9a-zA-Z, so quite human-friendly) which would be substantially shorter.  But before doing this, I needed to find the function to do it (predicting the person's first follow-up question), and I wanted to see how long a base-62 version of a UUID would be first (it's actually still pretty long).

Having drawn a blank looking for a ColdFusion-based answer, I did a general google and came up with this site which does the trick, albeit in JavaScript.  It's quite handy though.

Anyway, and apropos of not much given the bod on StackOverflow went a different way with his solution, here's a CF10 rendition of the JS function.  It's CF10-only (well: and Railo 4.x) because it has an inner function, which won't work on other  flavours / versions of CF.  It's be easy enough to defactor the inner function though, if you wanted to get this working on older platforms.

And here's some testing / proof:

And the results of said proof:
struct
DESCRIPTIONA fairly easy to visually-test example
NUMBER255
_BASEFROMdec
_BASETObin
_RESULT11111111
struct
DESCRIPTIONAnother one
NUMBERFFFF
_BASEFROMhex
_BASETOdec
_RESULT65535
struct
DESCRIPTIONUsing a bespoke 'alphabet' (OCTAL in this case)
NUMBER123
_BASEFROM01234567
_BASETOdec
_RESULT83
struct
DESCRIPTIONAnother one using a bespoke 'alphabet' (this is URL safe)
NUMBERB4E6B8A1CD20529D465BBF6D09631F87
_BASEFROMhex
_BASETO0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~
_RESULT1vObJLirBcoES50LQ62bFp
struct
DESCRIPTIONConverting to/from the same base
NUMBERB4E6B929E6FBC331CABCC807E587C80A
_BASEFROMhex
_BASETOhex
_RESULTB4E6B929E6FBC331CABCC807E587C80A
struct
DESCRIPTIONMulti-step proof it all works correctly: 1) from a GUID to BASE62
NUMBERB4E6BBC3C2BB42EFF461AB8B46C666BB
_BASEFROMhex
_BASETObase62
_RESULT5vm3ZkpsOUeKtOUL7xHAn1
struct
DESCRIPTIONMulti-step proof it all works correctly: 2) from BASE62 to BINARY
NUMBER5vm3ZkpsOUeKtOUL7xHAn1
_BASEFROMbase62
_BASETObin
_RESULT10110100111001101011101111000011110000101011101101000010111011111111010001100001101010111000101101000110110001100110011010111011
struct
DESCRIPTIONMulti-step proof it all works correctly: 3) from BINARY back to the original HEX
NUMBER10110100111001101011101111000011110000101011101101000010111011111111010001100001101010111000101101000110110001100110011010111011
_BASEFROMbin
_BASETOhex
_RESULTB4E6BBC3C2BB42EFF461AB8B46C666BB


I welcome any commentary or suggested improvements.  Indeed it's on github, so you can DIY if you like (I have no idea how github really works, I just commit my scratch code there for safe-keeping, but you can see the code there and [do stuff with it, I guess]).

Once it's up on CFLib, I'll post a link to it here too...  Done! (this is one of the benefits of being a CFLib approver... Ray will let me approve my own stuff :-)

Now: off to the forest I go (the rain has stopped, so shall get a dose of the outdoors whilst I can), but I'll come back later and not discuss closures, as was my original plan today...

Righto.

--
Adam