ichuan.net

自信打不死的心态活到老

911.im 短网址服务

虽然现在短网址服务已经泛滥了,但看到别人都有自己私人搭建的短网址服务,很是羡慕,于是准备自己搞个。

前段日子我爬了下3位数字字母的.im后缀域名,结果大吃一惊,有大量.im域名嗷嗷待注。我从结果里选了十来个,拿去问阿东,说我想做一个短网址网站,哪个域名好点?我向来是相信阿东的眼光的,这次他帮我选了 911.im 这个域名,说是 911 人尽皆知。

前两天我刚把人生中第一张visa信用卡申请到了,用它买了vps和域名。发现用信用卡在境外网站买东西真是方便,不用登录网银,只需输个密码就完成交易了。

昨晚上开始想一个短域名服务的架构。刚开始想用 redis 做存储,因为它速度快,而且天生就是为短网址这种类型网站用的。后来因为 redis 的数据持久化不太理想,应该只适合做缓存层,我怕丢数据,就放弃了 redis,选择了熟悉的 mysql。关于语言选型,最初想到这个网站功能会很简单,甚至不需要会话这一层,可以用 web.py 来做。考虑到最终部署,我 vps 上已经装了 flup,于是查了半天 nginx+flup+web.py 的配置,无果。后来想想,就这一个小网站,没必要这么认真,就选用熟悉的 django 开发了。

最后一个问题是短网址生成算法。这个我之前没看过其他短网址程序,不清楚他们是怎么做的。最初我想每个 url 取个 md5,md5 再映射到一个小点的字串。用 md5 主要是考虑索引。后来想想,可以这么做:按最简单的,每个 url 插数据库后有个唯一数字 id,这个 id 是 10 进制的,我只要将这个 id 映射到 另外一个进制(比如[0-9a-zA-Z]的62进制)就可以了。后来我先实现了一个 62 进制和 10 进制间相互转换的算法,再做其他的就很简单了。在这里分享下我的 62 进制算法:

chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

def decto62(dec):
    '''十进制转62进制,输入数字,返回字串'''
    ret = []
    while True:
        dec, a = divmod(dec, 62)
        ret.append(chars[a])
        if dec == 0:
            break
    ret.reverse()
    return ''.join(ret)

def decfrom62(num):
    '''62进制转十进制'''
    assert re.match(r'^[0-9a-zA-Z]+$', num)
    num = list(num)
    num.reverse()
    return reduce(lambda x,y:x+chars.find(num[y])*(62**y), range(len(num)), 0)

最后还需要个 favicon 吧。我简单用 mspaint 画了个 png 图,再转 ico 格式后就可以了。

这个短网址服务 911.im 已经上线,欢迎使用。

Comments