2012-03-09 15 views
0

Pythonで日付をURLセーフな文字列にシリアル化したいと思います。Pythonで安全な文字列に日付をシリアル化する

私はC++で覚えていますが、1970年1月1日以降の秒数を表す整数を使用していました。その後、Base64のURLセーフな文字列に変換できます。 C++の日付は、これらの整数を簡単に渡すことができるように設計されています。

Pythonでは、理想的には、日付を表すバイト配列を取得し、それをbase64.urlsafe_b64encode()に渡したいと考えています。その後、デシリアライズしたいときに、バイトをデコードしてdatetimeオブジェクトに戻すことができました。私はPythonでこれをどうやって行うのか見ていない。

私はdatetime.isoformat()を使うことができると信じていますが、それによって生成される文字列は不必要に長く見え、人間が読めるようにする必要はありません。翻訳を行うためのカスタム関数を書くこともできますが、可能であれば公式ライブラリコードを使用したいと思います。

何か不足していますか?これを行うための「簡単な」方法は、私が見ていないことですか?

ありがとうございます!

編集:

さて、ので、これは私は落ち着いものです。 @bgporterが以下で提案したものの変形です。私の目標は、datetime情報を不要なスペースを浪費することなくurl-safe文字列にすることでした。そのため、 "int"タイムスタンプからのバイトが直接base64になるようにコードを修正しました。 (base64でURLエンコードする必要はありません)。結果のタイムスタンプは、約8文字であり、このようになります:a7NaTw==

エンコードタイムスタンプ(URLセーフBase64文字列):

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

答えて

8

あなたは次のような意味です:

>>> 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進数の値は、文字列を使用して16進数の値を表します.64進数の場合、情報は少し圧縮されます。このコードを調べてみましたが、最初に "int"をタイムスタンプから基本10文字列(数字を表す通常の文字)に変換しました。これはおそらく十分に圧縮されており、開発者がタイムスタンプが早く来るかどうかを確認することも可能になります。ベース10のストリングからベース64に変換したとき、ストリングは実際に長くなったと思います。 –

+0

Base64は圧縮ではありません。それは8ビットバイト配列を取って7ビット配列に変換する方法です。これはAsciiのようです。これにより必然的に結果は元の(圧縮の反対の)バイトより多くなります。これは基数64の表現です。バイナリをasciiファイルに保存する場合はいつでも、base64を使用してください。 Wiki:https://en.wikipedia.org/wiki/Base64 – Atifm

+1

を参照してください。base64は '='を使用して文字列を3の倍数に埋め込み、 '='はURLセーフな文字ではないことに注意してください。 – Jens

関連する問題