random الدوال - كيف يمكنني إنشاء رقم عشوائي آمن مشفر في python؟




بايثون اكواد (5)

أنا بصدد إنشاء مشروع في python وأود إنشاء رقم عشوائي آمن مشفرًا ، كيف يمكنني فعل ذلك؟ لقد قرأت على الإنترنت أن الأرقام التي يولدها الموزع العشوائي العادي ليست آمنة بشكل مشفر ، وأن الدالة os.urandom(n) إلى سلسلة وليس إلى رقم.


Answers

لإنشاء رقم صحيح شبه عشوائي آمن مشفر ، يمكنك استخدام الشفرة التالية:

int(binascii.hexlify(os.urandom(n)),16)

حيث n عدد صحيح و n أكبر ، كلما كان العدد الصحيح الذي تم إنشاؤه أكبر.

سيكون عليك استيراد os و binascii أولاً.

يمكن أن تختلف نتيجة هذا الرمز حسب النظام الأساسي.


يقدم Python 3.6 وحدة أسرار جديدة ، والتي "توفر الوصول إلى مصدر الأمان الأكثر أمانًا الذي يوفره نظام التشغيل الخاص بك." لتوليد بعض الأرقام الآمنة المشفرة ، يمكنك الاتصال بـ secrets.randbelow() .

secrets.randbelow(n)

والتي ستعيد رقمًا بين 0 و n .


إذا كنت تريد رقمًا عشوائيًا n ، تحت Python 2.4+ ، فإن أسهل طريقة وجدتها هي

import random
random.SystemRandom().getrandbits(n)

لاحظ أن os.urandom() يستخدم os.urandom() ، وبالتالي فإن نتيجة هذه الطريقة جيدة فقط مثل تطبيق urandom() الخاص urandom() .


نظرًا لأنك تريد إنشاء أعداد صحيحة في نطاق معين ، فمن الأسهل استخدام فئة 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 يفعل ذلك لك.

لاحظ هذا الجزء من المستندات:

class.SystemRandom ([seed])

الفئة التي تستخدم الدالة os.urandom () لإنشاء أرقام عشوائية من المصادر التي يوفرها نظام التشغيل. غير متوفر على جميع الأنظمة. لا تعتمد على حالة البرامج والتسلسلات لا يمكن استنساخها. تبعاً لذلك ، فإن أساليب seed () و jumpahead () ليس لها أي تأثير ويتم تجاهلها. أساليب getstate () و setstate () رفع NotImplementedError إذا اتصلت.


تقترح وثائق بايثون ذات الصلة استخدام أسلوب التشفير EAFP (أسهل لطلب المغفرة من الإذن) . هذا يعني أن الرمز

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

أفضل من البديل

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

تقترح الوثائق هذا بالضبط بسبب شرط السباق الذي تمت مناقشته في هذا السؤال. بالإضافة إلى ذلك ، كما ذكر آخرون هنا ، هناك ميزة أداء في الاستعلام عن مرة واحدة بدلا من ضعف نظام التشغيل. وأخيرًا ، فإن الحجة المطروحة ، والتي قد تكون لصالح الشيفرة الثانية في بعض الحالات - عندما يعرف المطور أن البيئة التي يشغلها التطبيق - لا يمكن تأييدها إلا في الحالة الخاصة التي أنشأ فيها البرنامج بيئة خاصة نفسها (وغيرها من مثيلات البرنامج نفسه).

حتى في هذه الحالة ، هذه ممارسة سيئة ويمكن أن يؤدي إلى تصحيح الأخطاء عديمة الفائدة طويلة. على سبيل المثال ، يجب ألا تترك الحقيقة التي قمنا بتعيين أذونات الدليل بها يتم تعيين أذونات الظهور بشكل ملائم لأغراضنا. يمكن تركيب دليل الوالدين مع أذونات أخرى. بشكل عام ، يجب أن يعمل البرنامج دائمًا بشكل صحيح وأن لا يتوقع المبرمج بيئة معينة.





python random cryptography