4

Django認証でユーザー名の代わりに電子メールアドレスを使用する最良の方法を数時間調査しています。このトピックは何度も議論されてきましたが、得られた結果には一貫性がありません。

1)ここでの回答は、「@」文字を含めるだけでユーザー名と電子メールを区別するスニペットを指しています。ただし、電子メールとユーザー名の最大長は等しくなく、回答では考慮されません。

2) S.Lott (13 票) からの同じリンクからの 2 番目の回答は、admin.site でいくつかの黒魔術を行っています。コードが何をしているのか私には意味がありません.これは短くて甘い方法で受け入れられていますか?

3)次に、この解決策を見つけました。これはほぼ完璧に思えます(そして私には理にかなっています):

username = uuid.uuid4().hex[:30]

一意の Python 生成 ID の最初の 30 文字のみがユーザー名として選択されます。しかし、まだ衝突の可能性があります。その後、誰かが主張している投稿に出くわしました

md5 ハッシュの base64 エンコーディングには 25 文字あります

それが本当なら、メール アドレスの md5 ハッシュの base64 エンコーディングを使用して、100% の一意のユーザー名を保証できませんか。これも 30 文字未満ですか? これが本当なら、どうすればこれを達成できますか?

どうもありがとう、

4

3 に答える 3

4

あなたはこのようにそれを行うことができます:

>>> from hashlib import md5
>>> h = md5('email@example.com').digest().encode('base64')[:-1]
>>> _
'Vlj/zO5/Dr/aKyJiOLHrbg=='
>>> len(h)
24

最後の文字は改行であるため、無視してかまいません。衝突の可能性はMD5ハッシュと同じであり、base64でエンコードするときに情報が失われることはありません。

>>> original = md5('email@example.com').digest()
>>> encoded = original.encode('base64')
>>> original == encoded.decode('base64') 
True
于 2012-06-18T19:28:23.843 に答える
2

MD5ハッシュは常に16バイトの長さであり、Base64は3バイトから4文字のグループをエンコードします。したがって、(16/3は切り上げ)=> 3の6グループ、×4=Base64にエンコードされたMD5ハッシュの24文字。

ただし、上記のリンクされたウィキペディアのページには次のように記載されていることに注意してください。

ただし、MD5は衝突耐性がないことが示されています。

したがって、この方法では、電子メールアドレスから一意のユーザー名を取得することはできません。hashlibモジュールの助けを借りて、それらを作成するのは非常に簡単です:

>>> from hashlib import md5
>>> md5('foo@bar.com').digest().encode('base64').strip()
'862kBc6JC2+CBAlN6xLYqA=='
于 2012-06-18T19:42:26.287 に答える
2

UUIDは128ビットであるため、base64を直接適用して22文字の長い文字列を取得できます('=='ガンボが質問のコメントで示唆しているように、固定パディングを削除することにより)

>>> import base64
>>> len(base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip('='))
22

ここでは、urlsafe_b64encodeと のストリッピングを使用して、フィールドが好まない'='文字を回避します。User.username'/' '+''='

また、UUID には 2 ビットの固定'10'(したがって、16 進数表現の 17 番目の文字は常に8,9,A,B) と 4 ビットのバージョンがあります。wiki を確認してください。
したがって、4+2=6 ビットと 2 つの有効ビットを破棄して、30 文字の 16 進文字列を取得できます。

>>> s = uuid.uuid4().hex
>>> len(s[:12] + s[13:16] + s[17:])
30

このようにすると、単純に s を でスライスするときに 8 ではなく 2 つの有効ビットを捨てるだけになり、より優れた一意性s[:30]が期待できます(最大で uuid の 1/4 コーディング スペース)。

于 2012-06-19T06:35:30.637 に答える