TinyURL的实现原理

TinyURL[http://tinyurl.com]是一个在线web服务。它能将你任意输入的url简化一个由http://tinyurl.com/和一个随机字符串组成短url.访问短url会经过http://tinyurl.com服务跳转至长url.
比如,http://blog.csdn.net/bdss58经过短化后,生产http://tinyurl.com/y9abtgrp。在浏览器输入http://tinyurl.com/y9abtgrp,会自动跳转http://blog.csdn.net/bdss58

随机字符串由大小写字母和数字组成

        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",

tinyurl 是如何 完成http://tinyurl.com/y9abtgrphttp://blog.csdn.net/bdss58跳转的呢?

1. url入库

http://blog.csdn.net/bdss58出入数据库,得到一个唯一的自增id.

2. 唯一自增id 映射 到随机字符串

可以通过已定的hash算法将自增id转化为随机字符串,然后存入id对应数据库记录中

   id                   url                         tinyurl
89823    `http://blog.csdn.net/bdss58`       `http://tinyurl.com/y9abtgrp`

具体的hash算法可以是下面实现:

// convert a number to a base62 string
func convNumToBase62(num int) string {
    // base62 charactors
    chars := []string{
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    }
    var digitals []int
    for num != 0 {
        digitals = append(digitals, num%62)
        num = num / 62
    }

    reverse := func(arr []int) []int {
        for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
            arr[i], arr[j] = arr[j], arr[i]
        }
        return arr
    }
    digitals = reverse(digitals)
    var resultarr []string
    for _, elem := range digitals {
        resultarr = append(resultarr, chars[elem])
    }

    return strings.Join(resultarr, "")
}

3. 接收请求

tinyurl系统接收到 http://tinyurl.com/y9abtgrp的请求后,拿到随机字符y9abtgrp,推到出对应数据库记录的自增id,然后根据id查询数据库。

随机字符推到自增id的方法可以是如下:

func base62ToNum(str string) float64 {
    chars := []string{
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    }
    table := make(map[string]int)
    for i, e := range chars {
        table[e] = i
    }

    var result float64
    l := len(str)
    for i, e := range str {
        result = result + float64(table[string(e)])*math.Pow(62, float64(l-i-1))
    }

    return result
}

4. 跳转

经过步骤3,拿到数据库的自增id ,根据id拿出相应记录的url字段,根据url做跳转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值