Recipe Card Short Links

EasydesignAlso known as Base 62 Encoding

A recipe site prints a short link on the back of every recipe card, like rcp.ly/0021, so people can type it into a phone. Behind the link is a plain number: the recipe's row ID in the database. The short code is that number written in base 62, using the digits, the lowercase letters and the uppercase letters.

This is the core of a URL shortener (see Design a URL Shortener): a counter or an ID generator hands out unique numbers (Unique IDs), and base 62 turns each number into a short code and back again on every redirect.

Your task

Write a class ShortCode:

  • constructor(width): codes are padded on the left with "0" to at least width characters. A number that needs more characters gets a longer code; it is never cut.
  • encode(id): return the code for id.
  • decode(code): return the number a code stands for. Leading "0" characters add nothing, so "0021" and "21" both decode to the same number.

The 62 digits, in order of value from 0 to 61, are 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. So "a" is 10, "z" is 35, "A" is 36 and "Z" is 61. The number 0 is the single digit "0" before padding.

class ShortCode

Examples

Example 1
Input
new ShortCode(4)
.encode(125)
.decode("0021")
.decode("21")
Output
[null, "0021", 125, 125]
Why

125 = 2 × 62 + 1, so in base 62 it has the digits 2 and 1: "21". Padding to width 4 gives "0021". Decoding reads left to right: 0, then 0 × 62 + 0 = 0, then 0 × 62 + 2 = 2, then 2 × 62 + 1 = 125. Without the padding the answer is the same.

Example 2
Input
new ShortCode(7)
.encode(125000017)
.encode(3844)
.decode("008sudj")
Output
[null, "008sudj", "0000100", 125000017]
Why

125,000,017 needs 5 base-62 digits: s, u, d, j are 28, 30, 13, 19 and the leading 8 is 8, and 8 × 62⁴ + 28 × 62³ + 30 × 62² + 13 × 62 + 19 = 125,000,017. 3,844 is exactly 62², so it is written "100", the way 100 is 10² in decimal. Mixing up the order of the letters (uppercase before lowercase) would give a different code that decodes to a different recipe.

Constraints

  • 1 ≤ width ≤ 12
  • 0 ≤ id ≤ 9,007,199,254,740,991 (the largest safe integer in JavaScript)
  • Every code passed to decode uses only the 62 digits, has 1 to 12 characters, and stands for a number in the same range as id.
  • At most 1,000 calls per test.
Start with brute force

You could hand out codes by counting up through every string in order ("0", "1", …, "Z", "10", …) and keep a table from number to code. Encoding the millionth recipe means walking a million steps or storing a million rows, and decoding needs the reverse table too.

Base 62 is a formula in both directions, so neither table is needed: encoding and decoding take one step per character, and a code never has more than 12 characters here.

Hints

0 of 4 shown

Walkthrough and solution

Unlocks when you pass every test. Stuck for a while? Looking is fine too, as long as you then close it and write the code yourself.

Ctrl+Enter runs

Run your code to see results here. Run checks the examples. Submit checks every test, including hidden edge cases.

Write code