Convert Numbers from Base 16 to Base 64 in Python

The Problem

A web app that I built for a client uses tokens to keep track of user activity.  We email URLs to users with links that have these tokens in the query string.  They look like this:

https://super-long-domain.com/a-long-file-name.html?token=54410e10571a4a067e624293

The problem is that older versions of Outlook wrap long URLs like this to a new line, but don’t include any of the characters on the 2nd line in the hyperlink. So when a user clicks on the link, the wrapped text is not included. Obviously this breaks the web app. Grr.

The Solution

Microsoft recommends that you educate your users on how to repair the broken link themselves. This is not a great solution. Another option would be to send full HTML messages, but that seems like overkill and we like plain text just fine.

Instead we want to shorten the URL so it will fit on a single line in most email clients. There are a couple places we can attack it:

The HTML File Name

This web app is running on an Nginx web server so we can define a custom location for this file that has a shorter path. Now when we enter this in the browser:

https://super-long-domain.com/at/

We will be redirected automatically to here:

https://super-long-domain.com/a-long-file-name.html

The Token

Next we need to deal with the token itself. Again we can employ URL rewriting in Nginx to get started. We rewrite this:

https://super-long-domain.com/at/54410e10571a4a067e624293

We will be redirected automatically to here:

https://super-long-domain.com/a-long-file-name.html?token=54410e10571a4a067e624293

Shortening the length of the token itself would be even better. My first though was to convert the Token, which is a Hexadecimal number, to a base64 representation of the same number. I found a lot of examples of how to change encoding formats for text strings, but that doesn’t help. We need to convert the Hex number to a binary format and then to base16 to get a shorter result. In Python that looks like this:

base64.urlsafe_b64encode(bytes.fromhex('54410e10571a4a067e624293')).decode()

Then instead of a 24 character token you have a nice 16 character token:

VEEOEFcaSgZ-YkKT

The Result

Now the links look like this:

https://super-long-domain.com/at/VEEOEFcaSgZ-YkKT

Hopefully that will make super old versions of Outlook happier.

comments powered by Disqus