TinyURL[]是一个在线web服务。它能将你任意输入的url简化一个由/
和一个随机字符串组成短url.访问短url会经过服务跳转至长url.
比如,/bdss58
经过短化后,生产/y9abtgrp
。在浏览器输入/y9abtgrp,会自动跳转/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 是如何 完成/y9abtgrp
到 /bdss58
跳转的呢?
1. url入库
将/bdss58
出入数据库,得到一个唯一的自增id.
2. 唯一自增id 映射 到随机字符串
可以通过已定的hash算法将自增id转化为随机字符串,然后存入id对应数据库记录中
id url tinyurl
89823 `http:///bdss58` `http:///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 (resultarr, "")
}
3. 接收请求
tinyurl系统接收到 /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)])*(62, float64(l-i-1))
}
return result
}
4. 跳转
经过步骤3,拿到数据库的自增id ,根据id拿出相应记录的url字段,根据url做跳转。