pythonでプロジェクトを作成しています。暗号的に安全な乱数を作成したいのですが、どうすればよいですか?通常のランダマイザーによって生成された数値は暗号的に安全ではなく、関数os.urandom(n)
は数字ではなく文字列を返します。
このように ord
関数を _os.urandom
_ によって返されるバイトに適用するだけで、乱数のリストを取得できます。
_>>> import os
>>> os.urandom(10)
'm\xd4\x94\x00x7\xbe\x04\xa2R'
>>> type(os.urandom(10))
<type 'str'>
>>> map(ord, os.urandom(10))
[65, 120, 218, 135, 66, 134, 141, 140, 178, 25]
_
_os.urandom
_ドキュメントを引用して、
暗号化用途に適した
n
ランダムバイトの文字列を返します。この関数は、OS固有の乱数ソースからランダムバイトを返します。正確な品質はOSの実装に依存しますが、返されるデータは暗号化アプリケーションに十分なほど予測不能でなければなりません。 UNIXのようなシステムでは、これは_
/dev/urandom
_を照会し、WindowsではCryptGenRandom()
を使用します。
特定の範囲の整数を生成するため、代わりに_random.SystemRandom
_クラスを使用する方がはるかに簡単です。そのクラスのインスタンスを作成すると、random
モジュールのすべてのメソッドをサポートするオブジェクトが提供されますが、os.urandom()
を使用します。例:
_>>> from random import SystemRandom
>>> cryptogen = SystemRandom()
>>> [cryptogen.randrange(3) for i in range(20)] # random ints in range(3)
[2, 2, 2, 2, 1, 2, 1, 2, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0]
>>> [cryptogen.random() for i in range(3)] # random floats in [0., 1.)
[0.2710009745425236, 0.016722063038868695, 0.8207742461236148]
_
などurandom()
を直接使用して、生成するランダムバイトを希望する結果に変換する独自のアルゴリズムを考案する必要があります。それをしないでください;-) SystemRandom
はあなたのためにそれをします。
ドキュメントのこの部分に注意してください。
クラスrandom.SystemRandom([seed])
オペレーティングシステムが提供するソースから乱数を生成するためにos.urandom()関数を使用するクラス。すべてのシステムで利用できるわけではありません。ソフトウェアの状態に依存せず、シーケンスは再現できません。したがって、seed()およびjumpahead()メソッドは効果がなく、無視されます。 getstate()およびsetstate()メソッドは、呼び出されるとNotImplementedErrorを発生させます。
Python 3.6は、新しい secretsモジュール を導入します。これは、「オペレーティングシステムが提供する最も安全なランダム性のソースへのアクセスを提供します。 」暗号的に安全な番号を生成するために、 secrets.randbelow()
を呼び出すことができます。
secrets.randbelow(n)
0からn
の間の数値を返します。
n
- bit乱数が必要な場合、Python 2.4+の下で、私が見つけた最も簡単な方法は
_import random
random.SystemRandom().getrandbits(n)
_
SystemRandom
はos.urandom()
を使用するため、このメソッドの結果は、システムのurandom()
実装と同じくらい良いことに注意してください。
暗号的に安全な擬似乱数整数を生成するには、次のコードを使用できます。
int(binascii.hexlify(os.urandom(n)),16)
ここで、n
は整数であり、n
が大きいほど、生成される整数は大きくなります。
最初にos
とbinascii
をインポートする必要があります。
このコードの結果は、プラットフォームによって異なる場合があります。