在Django 2 Python 3中生成临时URL

在Django 2 Python 3中生成临时URL,python,django,python-3.x,Python,Django,Python 3.x,StackOverflow中有一个与此链接相同的问题: 但公认的答案代码是针对Python 2的,我将其转换为Python 3: import hashlib, zlib import pickle as pickle import urllib.request, urllib.parse, urllib.error my_secret = "michnorts" def encode_data(data): """Turn `data` into a hash and an en

StackOverflow中有一个与此链接相同的问题:

但公认的答案代码是针对Python 2的,我将其转换为Python 3:

import hashlib, zlib
import pickle as pickle
import urllib.request, urllib.parse, urllib.error

my_secret = "michnorts"

def encode_data(data):
    """Turn `data` into a hash and an encoded string, suitable for use with `decode_data`."""
    text = zlib.compress(pickle.dumps(data, 0)).encode('base64').replace('\n', '')
    m = hashlib.md5(my_secret + text).hexdigest()[:12]
    return m, text

def decode_data(hash, enc):
    """The inverse of `encode_data`."""
    text = urllib.parse.unquote(enc)
    m = hashlib.md5(my_secret + text).hexdigest()[:12]
    if m != hash:
        raise Exception("Bad hash!")
    data = pickle.loads(zlib.decompress(text.decode('base64')))
    return data

hash, enc = encode_data(['Hello', 'Goodbye'])
print(hash, enc)
print(decode_data(hash, enc))
但它有一个错误:

    text = zlib.compress(pickle.dumps(data, 0)).encode('base64').replace('\n', '')
AttributeError: 'bytes' object has no attribute 'encode'

我该如何解决这个问题

为了使您的代码适应Python 3,我提出了以下建议:

import hashlib, zlib
import pickle as pickle
import urllib.request, urllib.parse, urllib.error
import base64

my_secret = "michnorts"

def encode_data(data):
    """Turn `data` into a hash and an encoded string, suitable for use with `decode_data`."""
    compressed_text = zlib.compress(pickle.dumps(data, 0))
    text = base64.b64encode(compressed_text).decode().replace('\n', '')
    m = hashlib.md5(str.encode('{}{}'.format(my_secret, text))).hexdigest()[:12]
    return m, text

def decode_data(hash, enc):
    """The inverse of `encode_data`."""
    text = urllib.parse.unquote(enc)
    m = hashlib.md5(str.encode('{}{}'.format(my_secret, text))).hexdigest()[:12]
    if m != hash:
        raise Exception("Bad hash!")
    data = pickle.loads(zlib.decompress(base64.b64decode(text)))
    return data

hash, enc = encode_data(['Hello', 'Goodbye'])
print(hash, enc)
print(decode_data(hash, enc))
我需要考虑一些事情:

  • 在Python3中,编码/解码为base64的方法是使用
  • 为了将
    bytes
    对象转换为字符串,我使用
  • 要将字符串对象强制转换为
    字节
    对象,我使用
  • hashlib.md5
    函数接受一个
    bytes
    对象(字符串需要事先编码)
  • 我改变了将字符串(即
    str1+str2
    )与更具python风格的结构连接起来的方式:
    “{}{}”。格式(str1,str2)

我希望这会有所帮助;)

我特别推荐使用内置的机密模块。

只需再提供一个附加信息:
zlib.compress
在python2中返回
string
,在python3中返回
bytes
。请查看python文档中有关
byte
类的信息。