Skip to content

Latest commit

 

History

History
95 lines (68 loc) · 3.56 KB

018.md

File metadata and controls

95 lines (68 loc) · 3.56 KB

Difficulty: 🟡 Medium

Note: This is a companion problem to the System Design problem: Design TinyURL. TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. Design a class to encode a URL and decode a tiny URL.

There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.

Implement the Solution class:

  • Solution() Initializes the object of the system.
  • String encode(String longUrl) Returns a tiny URL for the given longUrl.
  • String decode(String shortUrl) Returns the original long URL for the given shortUrl. It is guaranteed that the given shortUrl was encoded by the same object.

Examples:

Example 1:

Input: url = "https://leetcode.com/problems/design-tinyurl"
Output: "https://leetcode.com/problems/design-tinyurl"

Explanation:
Solution obj = new Solution();
string tiny = obj.encode(url); // returns the encoded tiny url.
string ans = obj.decode(tiny); // returns the original url after decoding it.

Constraints:

  • 1 <= url.length <= 104
  • url is guranteed to be a valid URL.

Solutions

Simple solution

During class instance initialization we initialize key_value_store (in production Redis like distributed key value will be used) variable and define constant variables for short_url_template, code_length and random_string_length. In order to get shortUrl we first generate code by calculating sha256 digest, then encode digest using base64 and slice only 7 (code_length) characters. If generated code is not already in our key_value_store build shortUrl and return. Otherwise, reginarate code by appending random string to longUrl. Similar approach is used in real production.

Python3

import base64
import random
import string
import hashlib

class Codec:
    def __init__(self):
        self._code_length = 7
        self._random_string_length = 5
        self._key_value_store = {}
        self._short_url_template = "http://tinyurl.com/{code}"

    def _get_code(self, url):
        return base64.b64encode(hashlib.sha256(url.encode('utf-8')).digest()).decode("utf-8")[:self._code_length]

    def _get_random_string(self):
        return ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase, k=self._random_string_length))

    def encode(self, longUrl: str) -> str:
        """Encodes a URL to a shortened URL.
        """
        while True:
            code = self._get_code(longUrl)
            if code not in self._key_value_store:
                break
            longUrl += self._get_random_string()

        shortUrl = self._short_url_template.format(code=code)
        self._key_value_store[shortUrl] = longUrl
        return shortUrl
        

    def decode(self, shortUrl: str) -> str:
        """Decodes a shortened URL to its original URL.
        """
        return self._key_value_store.get(shortUrl, "")
        

# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.decode(codec.encode(url))

NB: If you want to get community points please suggest solutions in other languages as merge requests.