How do I create a URL shortener?

后端 未结 30 2044
我寻月下人不归
我寻月下人不归 2020-11-22 05:11

I want to create a URL shortener service where you can write a long URL into an input field and the service shortens the URL to \"http://www.example.org/abcdef\

相关标签:
30条回答
  • 2020-11-22 05:37

    Here is a decent URL encoding function for PHP...

    // From http://snipplr.com/view/22246/base62-encode--decode/
    private function base_encode($val, $base=62, $chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
        $str = '';
        do {
            $i = fmod($val, $base);
            $str = $chars[$i] . $str;
            $val = ($val - $i) / $base;
        } while($val > 0);
        return $str;
    }
    
    0 讨论(0)
  • 2020-11-22 05:37

    My Python 3 version

    base_list = list("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    base = len(base_list)
    
    def encode(num: int):
        result = []
        if num == 0:
            result.append(base_list[0])
    
        while num > 0:
            result.append(base_list[num % base])
            num //= base
    
        print("".join(reversed(result)))
    
    def decode(code: str):
        num = 0
        code_list = list(code)
        for index, code in enumerate(reversed(code_list)):
            num += base_list.index(code) * base ** index
        print(num)
    
    if __name__ == '__main__':
        encode(341413134141)
        decode("60FoItT")
    
    0 讨论(0)
  • 2020-11-22 05:38

    Don't know if anyone will find this useful - it is more of a 'hack n slash' method, yet is simple and works nicely if you want only specific chars.

    $dictionary = "abcdfghjklmnpqrstvwxyz23456789";
    $dictionary = str_split($dictionary);
    
    // Encode
    $str_id = '';
    $base = count($dictionary);
    
    while($id > 0) {
        $rem = $id % $base;
        $id = ($id - $rem) / $base;
        $str_id .= $dictionary[$rem];
    }
    
    
    // Decode
    $id_ar = str_split($str_id);
    $id = 0;
    
    for($i = count($id_ar); $i > 0; $i--) {
        $id += array_search($id_ar[$i-1], $dictionary) * pow($base, $i - 1);
    } 
    
    0 讨论(0)
  • 2020-11-22 05:39

    Why would you want to use a hash?

    You can just use a simple translation of your auto-increment value to an alphanumeric value. You can do that easily by using some base conversion. Say you character space (A-Z, a-z, 0-9, etc.) has 62 characters, convert the id to a base-40 number and use the characters as the digits.

    0 讨论(0)
  • 2020-11-22 05:40

    Not an answer to your question, but I wouldn't use case-sensitive shortened URLs. They are hard to remember, usually unreadable (many fonts render 1 and l, 0 and O and other characters very very similar that they are near impossible to tell the difference) and downright error prone. Try to use lower or upper case only.

    Also, try to have a format where you mix the numbers and characters in a predefined form. There are studies that show that people tend to remember one form better than others (think phone numbers, where the numbers are grouped in a specific form). Try something like num-char-char-num-char-char. I know this will lower the combinations, especially if you don't have upper and lower case, but it would be more usable and therefore useful.

    0 讨论(0)
  • 2020-11-22 05:40

    A Node.js and MongoDB solution

    Since we know the format that MongoDB uses to create a new ObjectId with 12 bytes.

    • a 4-byte value representing the seconds since the Unix epoch,
    • a 3-byte machine identifier,
    • a 2-byte process id
    • a 3-byte counter (in your machine), starting with a random value.

    Example (I choose a random sequence) a1b2c3d4e5f6g7h8i9j1k2l3

    • a1b2c3d4 represents the seconds since the Unix epoch,
    • 4e5f6g7 represents machine identifier,
    • h8i9 represents process id
    • j1k2l3 represents the counter, starting with a random value.

    Since the counter will be unique if we are storing the data in the same machine we can get it with no doubts that it will be duplicate.

    So the short URL will be the counter and here is a code snippet assuming that your server is running properly.

    const mongoose = require('mongoose');
    const Schema = mongoose.Schema;
    
    // Create a schema
    const shortUrl = new Schema({
        long_url: { type: String, required: true },
        short_url: { type: String, required: true, unique: true },
      });
    const ShortUrl = mongoose.model('ShortUrl', shortUrl);
    
    // The user can request to get a short URL by providing a long URL using a form
    
    app.post('/shorten', function(req ,res){
        // Create a new shortUrl */
        // The submit form has an input with longURL as its name attribute.
        const longUrl = req.body["longURL"];
        const newUrl = ShortUrl({
            long_url : longUrl,
            short_url : "",
        });
        const shortUrl = newUrl._id.toString().slice(-6);
        newUrl.short_url = shortUrl;
        console.log(newUrl);
        newUrl.save(function(err){
            console.log("the new URL is added");
        })
    });
    
    0 讨论(0)
提交回复
热议问题