2014-05-31
很多情况下,在url中过于明显的显示数据库中的一些信息并不是什么良好的实践。比如,在数据库中某个movie表:
CREATE TABLE movie(
id int primary key not null auto_increment,
path text
)
如果要以网页的形式播放这些视频,url格式可能如下:
http://www.example.com/play/{id}
例如要播放id为1的视频:
http://www.example.com/play/1
这种url很有规律性。对此,如果要有一个恶意的信息抓取程序住去依次页面信息:
http://www.example.com/play/1
http://www.example.com/play/2
http://www.example.com/play/3
http://www.example.com/play/4
...
example.com
网站的拥有者一般不乐意这种情况发生。要避免这种情况,使用对称加密的方式处理这些id是一个很好的解决方案。
hashids
是一个很好的选择,其提供了js、ruby、python、java、php、perl、coffeescript、objective-C、Go、Lua、Node.js等编程语言的实现,具体请移步官网hashids。
使用hashids,可以将1
转换为4q2VolejRejNmGQB
(当然,也能转换成其他的字符串,详见下文),也可以将4q2VolejRejNmGQB
逆转为1
。
下面是python版本教程的简单翻译,原文见hashids-python 。
安装
pip install hashids
如何使用
如何导入
from hashids import Hashids
hashids = Hashids()
基本使用
加密单个整数:
hashid = hashids.encrypt(123) # 'Mj3'
解密一个哈希值(加密后的值):
ints = hashids.decrypt('Mj3') # (123,)
加密多个整数:
hashid = hashids.encrypt(123, 456, 789) # 'El3fkRIo3'
解密多个整数:
ints = hashids.decrypt('1B8UvJfXm') # (517, 729, 185)
使用自定义的盐值(salt)
例子1:
hashids = Hashids(salt='this is my salt 1')
hashid = hashids.encrypt(123) # 'nVB'
例子2:
hashids = Hashids(salt='this is my salt 2')
hashid = hashids.encrypt(123) # 'ojK'
盐值字串的长度最好在6到32之间。
控制加密后字串的长度
加密:
hashids = Hashids(min_length=16)
hashid = hashids.encrypt(1) # '4q2VolejRejNmGQB'
解密:
hashids = Hashids(min_length=16)
hashids.decrypt('4q2VolejRejNmGQB') # (1,)
使用自定义的字母表
加密得到的字符串中的所有字符都来自字母表,默认的字母表是:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
字母表是可以自定义的,例如全部是小写字母:
hashids = Hashids(alphabet='abcdefghijklmnopqrstuvwxyz')
hashid = hashids.encrypt(123456789) # 'kekmyzyk'
自定义的字母表中的字符至少应含有16个字符。
随机性
hashids的主要目标是混淆id,这并不意味着它适合用来加密或者压缩。虽然是对称加密,不过其“随机性”还是很好的。
例如加密重复的数字:
hashids = Hashids("this is my salt")
hashids.encrypt(5, 5, 5, 5) # '1Wc8cwcE'
加密递增的数字:
hashids.encrypt(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # 'kRHnurhptKcjIDTWC3sx'
hashids.encrypt(1) # 'NV'
hashids.encrypt(2) # '6m'
hashids.encrypt(3) # 'yD'
hashids.encrypt(4) # '2l'
hashids.encrypt(5) # 'rD'
会不会生成的字串里有脏话?
hashids的算法尝试避免生成常见的英文脏话,方法是不让下面的这些字符相邻:
c, C, s, S, f, F, h, H, u, U, i, I, t, T