2012-03-09 2 views
0

Я хотел бы сериализовать дату в python на URL-адрес безопасной строки.Сериализовать дату для безопасной строки в Python

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

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

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

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

Спасибо!

Edit:

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

Encode метка времени (URL-сейф Base64 строки):

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

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

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

ответ

8

You означают следующее:

>>> 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) 

?

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

+0

Целью Base64 было сохранить информацию сжатую. Шестнадцатеричное значение использует строковые символы для представления значения в базе 16. С базой 64 информация немного сжата. Хотя вы просматриваете этот код, вы сначала превратили «int» из метки времени в базовую строку 10 (просто обычные символы, представляющие цифры). Это, вероятно, достаточно сжато, а также позволяет разработчику следить за тем, какие временные метки появились раньше и позже. Когда вы переводили из базы 10 строк в базу 64, я думаю, что строка фактически стала длиннее. –

+0

Base64 не является сжатием. Это способ взять и 8-битный байт-массив и превратить его в 7-битный массив, который, по-видимому, является Ascii. Это обязательно приводит к тому, что результат будет больше байтов, чем исходный (напротив сжатия). Это представление radix-64. В любое время, когда вы хотите сохранить двоичный файл в файле ascii, используйте base64. См. Wiki: https://en.wikipedia.org/wiki/Base64 – Atifm

+1

Обратите внимание, что base64 использует '=' для того, чтобы поместить строку в несколько из трех, и что '=' не является символом, безопасным для URL. – Jens