网址压缩的调研分析(续)
25 July 2014
将Python实现的short_url.py改写成了Golang实现。
上文提到在GitHub找到一个Python实现的打散ID压缩成62进制的算法,今天抽空翻译成了Golang。虽然说代码都看懂了,但是动手翻译的时候发现还是有一些细节的东西挺有意思的。代码放到了go_code项目下。源码也贴在这里。
import (
"bitbucket.org/tebeka/base62"
"fmt"
)
var (
DEFAULT_BLOCK_SIZE = uint(24)
DEFAULT_ENCODER *UrlEncoder
MIN_LENGTH = 5
)
type UrlEncoder struct {
BlockSize uint
Mask uint64
Mapping []uint
}
func NewUrlEncoder(blocksize uint) (u *UrlEncoder) {
u = new(UrlEncoder)
u.BlockSize = blocksize
u.Mask = (1 << blocksize) - 1
for i := uint(0); i < blocksize; i++ {
u.Mapping = append(u.Mapping, blocksize-i-1)
}
return u
}
func (this *UrlEncoder) Encode(n uint64) uint64 {
return (n & ^this.Mask) | this.encode(n&this.Mask)
}
func (this *UrlEncoder) encode(n uint64) (result uint64) {
for i, b := range this.Mapping {
if n&(1<<uint(i)) > 0 {
result |= (1 << b)
}
}
return result
}
func (this *UrlEncoder) Decode(n uint64) uint64 {
return (n & ^this.Mask) | this.decode(n&this.Mask)
}
func (this *UrlEncoder) decode(n uint64) (result uint64) {
for i, b := range this.Mapping {
if n&(1<<uint(b)) > 0 {
result |= (1 << uint(i))
}
}
return result
}
func (this *UrlEncoder) Enbase(n uint64) string {
return base62.Encode(n)
}
func (this *UrlEncoder) Debase(n string) uint64 {
return base62.Decode(n)
}
func (this *UrlEncoder) EncodeUrl(n uint64) (short_url string) {
return DEFAULT_ENCODER.Enbase(DEFAULT_ENCODER.Encode(n))
}
func DecodeUrl(short_url string) (n uint64) {
return DEFAULT_ENCODER.Decode(DEFAULT_ENCODER.Debase(short_url))
}
func init() {
DEFAULT_ENCODER = NewUrlEncoder(DEFAULT_BLOCK_SIZE)
}
func Disperse(i uint64) (disperse_i uint64) {
fmt.Println(DEFAULT_ENCODER)
a := DEFAULT_ENCODER.Encode(i)
b := DEFAULT_ENCODER.Enbase(a)
c := DEFAULT_ENCODER.Debase(b)
disperse_i = DEFAULT_ENCODER.Decode(c)
fmt.Println(i, a, b, c, disperse_i)
return disperse_i
}
里面用到了别人实现的62进制压缩包。实现原理在上一篇文章《网址压缩的调研分析》的最后一篇文章里面已经说得很清楚了,可以参考那篇文章。
下面接着说一下短网址的调研情况。这之前,都只是讲了算法的实现,而具体的存储数据库还没有介绍。GitHub上面与此相关的项目都是使用MySQL实现的。用数据库实现确实很方便,表很简单,两个字段ID和网址就可以了。但是,在数据结构是如此简单的情况下,一般都是使用Redis来实现。Redis是将Key缓存在内存当中,查询速度快。然而,MySQL有一个Redis无法比拟的优势:Redis只能通过Key查询Value的值,而数据库可以实现双向映射。在用户添加网址的时候,需要去库里查询是否已经存在于库中了,这时需要使用网址来作为查询字段;而在解析短网址的时候,还会需要通过ID查询原始网址。这里就用到了双向查询。
看来使用ID进行编码短网址的方式,目前只能使用传统数据库了。
参考文献
原文链接:网址压缩的调研分析(续),转载请注明来源!
–EOF–