加密字符串以获得固定长度

时间:2014-05-07 14:35:25

标签: python django url encoding compression

假设我有以下可能的字符串值:

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库中的解决方案而无需安装新软件包。

4 个答案:

答案 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)非常低。