假设我有以下可能的字符串值:
exp="110"
exp="110-120"
exp="110-120-211"
实际上,这是从URL获得的GET参数。 exp
会变得非常大,所以我想缩短它(加密它)。不是出于安全原因,而是因为我不希望它变得冗长和丑陋。
所以我想加密exp
成为一个固定长度的短字符串,比如说15。有可能以某种方式吗?像这样:
encrypt("110") results in "Ax1234B"
encrypt("110-120") results in "85xHdjX"
我正在使用python btw
修改
忘了提及:我还需要一个decrypt
功能。此外,我更喜欢标准python库中的解决方案而无需安装新软件包。
答案 0 :(得分:1)
你的琴弦有多长时间了?如果它们足够长,您可以使用zlib
(或标准库中的其他压缩模块)压缩它们,然后在其上运行base64。
>>> z = base64.encodestring(zlib.compress("123"))
>>> print z
eJwzNDIGAAEtAJc=
>>> zlib.decompress(base64.decodestring(z))
'123'
这不会缩小你的字符串,除非它们很长,但是(在我的测试中,原始字符串中有36个字符)。你也没有固定长度,但我不相信有任何方法可以实现这一点。
答案 1 :(得分:0)
如果安全性根本不是问题,而您只想混淆和缩小,可以使用base64吗?它在Javascript和Python中实现,因此您可以在前端轻松编码并在后端对其进行解码。
但是,这不会给你一个固定的长度,除非你刻意填充到一个更长的实际长度。
答案 2 :(得分:0)
不,它不可能以可逆的方式将任意大的数据集合到固定长度中。你需要更好地定义传递的内容。
例如:if:
如果这些是真的,你可以将列表作为位打包成一个固定大小的单个二进制流,最大位数作为最大数,然后base64对其进行编码。这将是固定的长度和可逆的。
答案 3 :(得分:0)
如果要将网址转换为固定长度的字符串;您可以使用散列函数和数据库来检索给定其散列的URL:
import base64
import hashlib
import sqlite3
db = sqlite3.connect('urls.sqlite3')
db.execute('''CREATE TABLE IF NOT EXISTS urls
(hash BLOB PRIMARY KEY, url TEXT)''')
def shorten(url):
h = sqlite3.Binary(hashlib.sha256(url.encode('ascii')).digest())
with db:
db.execute('INSERT OR IGNORE INTO urls VALUES (?, ?)', (h, url))
return base64.urlsafe_b64encode(h).decode('ascii')
def geturl(shortened_url):
h = sqlite3.Binary(base64.urlsafe_b64decode(shortened_url.encode('ascii')))
with db:
url = db.execute('SELECT url FROM urls WHERE hash=?', (h,)).fetchone()
if url is None:
raise KeyError(shortened_url)
return url[0]
urls = ["110", "110-120", "110-120-211"]
width = max(map(len, urls))
for url in urls:
slug = shorten(url)
assert url == geturl(slug)
print('{url:{width}} -> {slug}'.format(**vars()))
110 -> m9sq9nmSBKKZxgOZS45ADksf1iXv23QGbMhp_uQsnfM=
110-120 -> aKGvjidWggSkQ1wBnZoi5f67KlUS1pvoVyhX8Rd04P0=
110-120-211 -> C8LD7lCh5Tm8XCoWJep9OAfSnMikLU5lgQChe-wfQho=
输出始终具有相同的长度,但是长(或短)输入URL是。
对于具有良好算法的足够长的哈希,对于生成的任何实际数量的url哈希,冲突概率(产生相同哈希的不同URL)非常低。