Сериализация даты в безопасную строку URL в Python - PullRequest
2 голосов
/ 10 марта 2012

Я бы хотел сериализовать Date в python в строку URL Safe.

Я помню, что в C ++ я просто использовал целое число, представляющее количество секунд с 1 января 1970 года (или что-то в этом роде). Тогда я мог бы превратить его в строку Base64, безопасную для URL. Даты С ++ были разработаны, чтобы можно было легко передавать эти целые числа.

В идеале в Python я хотел бы получить байтовый массив, представляющий дату, а затем передать его в base64.urlsafe_b64encode (). Затем, когда я хотел десериализовать, я мог бы расшифровать байты и передать их обратно в объект datetime. Я не вижу, как это сделать в Python, хотя.

Полагаю, я мог бы использовать datetime.isoformat (), но созданная таким образом строка кажется излишне длинной, и мне не нужно, чтобы она читалась человеком. Я мог бы также написать собственные функции для перевода, но я бы хотел использовать официальный библиотечный код, если это возможно.

Я что-то упустил? Есть ли "простой" способ сделать это, чего я не вижу?

Спасибо!

Изменить:

Хорошо, поэтому я остановился на этом. Это вариант того, что @bgporter предложил ниже. Моя цель состояла в том, чтобы превратить информацию о дате и времени в строку, безопасную для URL, не занимая слишком много ненужного пространства, поэтому я изменил код так, чтобы байты из временной метки «int» непосредственно кодировались в base64, а не переводились в строку цифр (которые не должны быть в кодировке base64 url). Полученная временная метка составляет около 8 символов и выглядит следующим образом: a7NaTw==:

Кодирование временной метки (строка Base64, безопасная для URL):

url_safe_timestamp = base64.urlsafe_b64encode(struct.pack('L', int(time.time())))

Метка времени декодирования (объект Date):

decoded_timestamp = datetime.datetime.fromtimestamp(float(struct.unpack('L', base64.urlsafe_b64decode(url_safe_timestamp))[0]))

Ответы [ 2 ]

8 голосов
/ 10 марта 2012

Вы имеете в виду, как это:

>>> import base64
>>> import time
>>> encoded = base64.urlsafe_b64encode("%d" % int(time.time()))
>>> print encoded
'MTMzMTMyOTE5NA=='
>>> decoded = int(base64.urlsafe_b64decode(encoded))
>>> print decoded
1331329194
>>> import datetime
>>> datetime.datetime.fromtimestamp(decoded)   
datetime.datetime(2012, 3, 9, 16, 39, 54)

(и я не уверен, почему кодировка base 64 здесь лучше, чем просто использование шестнадцатеричного значения - чего мне не хватает?)

0 голосов
/ 20 февраля 2019
from base64 import urlsafe_b64encode
print(
    urlsafe_b64encode(
        bytes.fromhex(
            hex(int(time() * 1000)).lstrip('0x').rjust(12, '0')
        )
    ).decode('ascii').rstrip('=')
)

# prints: AWkLDNvo
...