Bite 250. PyBites URL Shortener

URL shortening is a technique on the World Wide Web in which a Uniform Resource Locator (URL) may be made substantially shorter and still direct to the required page (Wikipedia). Let's build one for PyBites!

You would think that there is some complex math involved here, but that's not really what's going on. The only thing that's encoded is the database record ID of the URL entry.

Since we're only interested in encoding 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ we will be encoding the values into Base62. Why 62? Well because if you add up all of those characters, they total 62! If you wanted to use other symbols, that would be a great exercise for you to expand on what you learn here.

If you don't know how to encode numbers into other base formats, here's a quick little tutorial:

# encode(100):
num = 100
# num % base62
remainder = 100 % 62 = 38
# codex[remainder]
result = codex[38]  # "C"

# floor(num / base62)
queue = floor(100 / 62)  # 1

while queue:
# queue % base62
remainder = 1 % 62  # 1
# floor(queue / base62)
queue = floor(1 / 62)  # 0
# codex[remainder] + result
result = codex[1] + "C"  # "1C"
return result

# decode("1C")
value = 0
for char in result:
# first pass char = 1
# value = base62 * value + codex.find(char)
# value = 62 * 0 + codex.find("1")
# value = 0 + 1
value = 1
# second pass char = C
# value = base62 * value + codex.find(char)
# value = 62 * 1 + codex.find("C")
# value = 62 + 38
value = 100
return value

Instead of using an SQL database or something like that, for this Bite we'll just be using the LINKS dictionary. I've provided some code to get you started, but you'll have to complete the following functions:

• encode: Encodes the number passed into Base62
• decode: Decodes the string passed back into Base10
• redirect: Takes a shortened URL and returns the URL stored in LINKS
• Verifies that domain of shortened url is from https://pybit.es, if not returns error message INVALID
• Checks to see if the record exists, if not return error message NO_RECORD
• Returns the stored URL
• Encodes the next_record passed to it
• Returns the shortened URL

And apart from the included tests, here you can see it in action in the REPL:

>>> from url_shortener import encode, decode, redirect, shorten_url
>>> encode(5120)
'1kA'
>>> decode('1kA')
5120
>>> shorten_url("https://python.org", 7000)
'https://pybit.es/1OU'
>>> redirect('https://pybit.es/1OU')
'https://python.org'

An URL shortener is a pretty useful service to provide, so let's give it a shot. Have fun and keep calm and code in Python!