zlib.crc32或zlib.adler32能安全地用于URL中的主键掩码吗?
在《Django设计模式》这本书中,作者建议使用zlib.crc32来隐藏URL中的主键。经过一些简单的测试,我发现crc32大约有一半的时间会产生负数,这在URL中使用似乎不太合适。而zlib.adler32似乎不会产生负数,但它被描述为比CRC要“弱一些”。
- 这种方法(无论是CRC还是Adler-32)在URL中作为主键的替代品安全吗?也就是说,它能避免冲突吗?
- 这个“弱一些”的Adler-32能否满足这个任务的要求?
- 那怎么反向操作呢?也就是说,如何从校验和中找回原来的主键?
3 个回答
1
经过进一步调查,这看起来真的是个糟糕的主意:
In [11]: s = set([zlib.crc32(str(x)) for x in xrange(20000000)])
In [12]: len(s)
Out[12]: 19989760
In [13]: 20000000 - len(s)
Out[13]: 10240
在2000万个主键中,有10240个冲突。
1
你可以把这个32位的CRC值看作一个无符号整数。
1
问题不在于对值进行哈希处理,而在于如何把哈希值映射回原来的键。即使出现了冲突,你也可以通过增加数值来找到一个未被使用的哈希值。
哈希值之所以被用在比如身份验证这样的场景,是因为已经有一个键(比如用户名)可以用来找到对应的记录。到那时,只需要把给定的哈希值和存储的哈希值进行比较就可以了。如果你是用哈希值来隐藏键,那就比单纯比较要复杂。不过,如果把哈希值本身当作键来用,就能解决这个问题。