How do I create a URL shortener?

后端 未结 30 2043
我寻月下人不归
我寻月下人不归 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:32
    // simple approach
    
    $original_id = 56789;
    
    $shortened_id = base_convert($original_id, 10, 36);
    
    $un_shortened_id = base_convert($shortened_id, 36, 10);
    
    0 讨论(0)
  • 2020-11-22 05:32

    I have a variant of the problem, in that I store web pages from many different authors and need to prevent discovery of pages by guesswork. So my short URLs add a couple of extra digits to the Base-62 string for the page number. These extra digits are generated from information in the page record itself and they ensure that only 1 in 3844 URLs are valid (assuming 2-digit Base-62). You can see an outline description at http://mgscan.com/MBWL.

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

    Did you omit O, 0, and i on purpose?

    I just created a PHP class based on Ryan's solution.

    <?php
    
        $shorty = new App_Shorty();
    
        echo 'ID: ' . 1000;
        echo '<br/> Short link: ' . $shorty->encode(1000);
        echo '<br/> Decoded Short Link: ' . $shorty->decode($shorty->encode(1000));
    
    
        /**
         * A nice shorting class based on Ryan Charmley's suggestion see the link on Stack Overflow below.
         * @author Svetoslav Marinov (Slavi) | http://WebWeb.ca
         * @see http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener/10386945#10386945
         */
        class App_Shorty {
            /**
             * Explicitly omitted: i, o, 1, 0 because they are confusing. Also use only lowercase ... as
             * dictating this over the phone might be tough.
             * @var string
             */
            private $dictionary = "abcdfghjklmnpqrstvwxyz23456789";
            private $dictionary_array = array();
    
            public function __construct() {
                $this->dictionary_array = str_split($this->dictionary);
            }
    
            /**
             * Gets ID and converts it into a string.
             * @param int $id
             */
            public function encode($id) {
                $str_id = '';
                $base = count($this->dictionary_array);
    
                while ($id > 0) {
                    $rem = $id % $base;
                    $id = ($id - $rem) / $base;
                    $str_id .= $this->dictionary_array[$rem];
                }
    
                return $str_id;
            }
    
            /**
             * Converts /abc into an integer ID
             * @param string
             * @return int $id
             */
            public function decode($str_id) {
                $id = 0;
                $id_ar = str_split($str_id);
                $base = count($this->dictionary_array);
    
                for ($i = count($id_ar); $i > 0; $i--) {
                    $id += array_search($id_ar[$i - 1], $this->dictionary_array) * pow($base, $i - 1);
                }
                return $id;
            }
        }
    ?>
    
    0 讨论(0)
  • 2020-11-22 05:35

    You could hash the entire URL, but if you just want to shorten the id, do as marcel suggested. I wrote this Python implementation:

    https://gist.github.com/778542

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

    Very good answer, I have created a Golang implementation of the bjf:

    package bjf
    
    import (
        "math"
        "strings"
        "strconv"
    )
    
    const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    
    func Encode(num string) string {
        n, _ := strconv.ParseUint(num, 10, 64)
        t := make([]byte, 0)
    
        /* Special case */
        if n == 0 {
            return string(alphabet[0])
        }
    
        /* Map */
        for n > 0 {
            r := n % uint64(len(alphabet))
            t = append(t, alphabet[r])
            n = n / uint64(len(alphabet))
        }
    
        /* Reverse */
        for i, j := 0, len(t) - 1; i < j; i, j = i + 1, j - 1 {
            t[i], t[j] = t[j], t[i]
        }
    
        return string(t)
    }
    
    func Decode(token string) int {
        r := int(0)
        p := float64(len(token)) - 1
    
        for i := 0; i < len(token); i++ {
            r += strings.Index(alphabet, string(token[i])) * int(math.Pow(float64(len(alphabet)), p))
            p--
        }
    
        return r
    }
    

    Hosted at github: https://github.com/xor-gate/go-bjf

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

    Here is my PHP 5 class.

    <?php
    class Bijective
    {
        public $dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    
        public function __construct()
        {
            $this->dictionary = str_split($this->dictionary);
        }
    
        public function encode($i)
        {
            if ($i == 0)
            return $this->dictionary[0];
    
            $result = '';
            $base = count($this->dictionary);
    
            while ($i > 0)
            {
                $result[] = $this->dictionary[($i % $base)];
                $i = floor($i / $base);
            }
    
            $result = array_reverse($result);
    
            return join("", $result);
        }
    
        public function decode($input)
        {
            $i = 0;
            $base = count($this->dictionary);
    
            $input = str_split($input);
    
            foreach($input as $char)
            {
                $pos = array_search($char, $this->dictionary);
    
                $i = $i * $base + $pos;
            }
    
            return $i;
        }
    }
    
    0 讨论(0)
提交回复
热议问题