5

我的数据库中的每个用户对象都有一个增量 ID(1、2、3,...)。查看用户配置文件的 URL 包含用户对象的 ID;例如http://www.example.com/users/1。这样每个人都可以看到网站上有多少用户,用户群的增长速度等等。我不想泄露这些信息。

我想将增量 ID 转换为 Base58 格式的固定长度字符串,因此 URL 看起来像http://www.example.com/users/2WNrx2jq184另外,我需要将字符串转换回原身份证。逆向函数应该不容易逆向工程。

我为此目的找到的最好的 Python 代码是https://github.com/JordanReiter/django-id-obfuscator。这非常好,但在某些情况下,它会添加一个0和/或.字符,这会导致字符串不在 Base58 中且长度不固定。(参见utils.py第 24 和 29 行。)

如何改进 django-id-obfuscator 以生成固定长度的 base58 混淆 ID,或者如何在 Python 中创建此类混淆 ID?

4

2 回答 2

6

如果您想正确执行此操作,请获取您的用户 ID,用前导零填充,然后使用 AES 之类的东西对其进行加密,并使用 base58 对结果进行编码。要取回 ID,只需解码、解密和int()结果。

所以对于加密:

>>> from Crypto.Cipher import AES
>>> import base64
>>> obj = AES.new('yoursecretkeyABC')
>>> x = base64.encodestring(obj.encrypt("%016d"%1))
>>> x
'tXDxMg1YGb1i0V29yCCBWg==\n'

和解密

>>> int(obj.decrypt(base64.decodestring(x)))
1

如果您可以使用弱加密,您也可以简单地使用密钥对填充的 ID 进行异或运算:

>>> key = [33, 53, 2, 42]
>>> id = "%04d" % 1
>>> x = ''.join([chr(a^ord(b)) for a, b in zip(key, id)])
>>> x
'\x11\x052\x1b'
>>> int(''.join([chr(a^ord(b)) for a, b in zip(key, x)]))
1

但这不太安全,因为您永远不应该对多条消息使用相同的 OTP。还要确保密钥与填充 ID 的长度相同。

于 2012-06-15T09:44:11.053 回答
1

这是我偶然发现的一个老问题。我最近发现了hashids解决这个问题的库,它可用于多种编程语言:

http://hashids.org

于 2016-10-28T19:45:47.557 回答