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 | |
---|---|

DESCRIPTION | A fairly easy to visually-test example |

NUMBER | 255 |

_BASEFROM | dec |

_BASETO | bin |

_RESULT | 11111111 |

struct | |
---|---|

DESCRIPTION | Another one |

NUMBER | FFFF |

_BASEFROM | hex |

_BASETO | dec |

_RESULT | 65535 |

struct | |
---|---|

DESCRIPTION | Using a bespoke 'alphabet' (OCTAL in this case) |

NUMBER | 123 |

_BASEFROM | 01234567 |

_BASETO | dec |

_RESULT | 83 |

struct | |
---|---|

DESCRIPTION | Another one using a bespoke 'alphabet' (this is URL safe) |

NUMBER | B4E6B8A1CD20529D465BBF6D09631F87 |

_BASEFROM | hex |

_BASETO | 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~ |

_RESULT | 1vObJLirBcoES50LQ62bFp |

struct | |
---|---|

DESCRIPTION | Converting to/from the same base |

NUMBER | B4E6B929E6FBC331CABCC807E587C80A |

_BASEFROM | hex |

_BASETO | hex |

_RESULT | B4E6B929E6FBC331CABCC807E587C80A |

struct | |
---|---|

DESCRIPTION | Multi-step proof it all works correctly: 1) from a GUID to BASE62 |

NUMBER | B4E6BBC3C2BB42EFF461AB8B46C666BB |

_BASEFROM | hex |

_BASETO | base62 |

_RESULT | 5vm3ZkpsOUeKtOUL7xHAn1 |

struct | |
---|---|

DESCRIPTION | Multi-step proof it all works correctly: 2) from BASE62 to BINARY |

NUMBER | 5vm3ZkpsOUeKtOUL7xHAn1 |

_BASEFROM | base62 |

_BASETO | bin |

_RESULT | 10110100111001101011101111000011110000101011101101000010111011111111010001100001101010111000101101000110110001100110011010111011 |

struct | |
---|---|

DESCRIPTION | Multi-step proof it all works correctly: 3) from BINARY back to the original HEX |

NUMBER | 10110100111001101011101111000011110000101011101101000010111011111111010001100001101010111000101101000110110001100110011010111011 |

_BASEFROM | bin |

_BASETO | hex |

_RESULT | B4E6BBC3C2BB42EFF461AB8B46C666BB |

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