ما هو مولد الأرقام العشوائية؟
مولد الأرقام العشوائية (RNG) هو نظام ينتج أرقاماً عشوائية أو شبه عشوائية. وتعتمد إمكانية التنبؤ بالرقم التالي عملياً على نوع المولد المستخدم؛ إذ تعتمد بعض المولدات على ظاهرة فيزيائية، بينما يحسب بعضها الآخر الأرقام باستخدام خوارزمية برمجية، وهناك خوارزميات صُممت بحيث لا يستطيع حتى من اطّلع على نتائجها التنبؤ بما سيأتي بعدها. إن المظهر العشوائي واستحالة التنبؤ صفتان مختلفتان تماماً، ويتمحور معظم هذا المقال حول توضيح الفارق بينهما.
مولدات الأرقام العشوائية العتادية
يستمد مولد الأرقام العشوائية العتادي (HRNG)، الذي يُعرف أيضاً بمولد الأرقام العشوائية الحقيقي (TRNG)، أرقامه من عمليات فيزيائية فعلية. وأقدم هذه الطرق هي ظواهر ميكانيكية يمكن رؤيتها بالعين المجردة: رمي قطعة نقدية، أو دحرجة نرد، أو تدوير عجلة الروليت. ورغم أن قوانين الميكانيكا الكلاسيكية تصف حركة كل منها وصفاً دقيقاً، فإن العجلة متقنة الصنع تظل مستحيلة التنبؤ في الممارسة العملية، لأن أدنى تفاوت في ظروف بدء دورانها يتضخم ليقود إلى نتائج مختلفة كلياً.
أما المولدات العتادية الحديثة فتقيس ظواهر مجهرية دقيقة: مثل ضوضاء الطلقة والضوضاء الحرارية في الدوائر الإلكترونية، والتشويش الجوي، والظواهر الكمومية. وتُعد هذه الظواهر مصادر ممتازة للإنتروبيا — وهي مقدار عدم القدرة على التنبؤ الذي يمكن قياسه — لكن المصدر الفيزيائي ليس مثالياً بطبيعته؛ فقد يعاني من عدم تكافؤ الفرص في نتائجه، أو ينحرف بمرور الوقت، أو يتعطل تماماً. لذلك يتعين تقييم جودته ومراقبتها ومعالجة قيمه الناتجة عند الضرورة، وهو ما توضحه معايير متخصصة مثل NIST SP 800-90B. وتُستخدم المصادر العتادية حيثما كان الضمان الأمني بالغ الأهمية — ولا سيما في علم التشفير، حيث توفر المادة الأولية غير المتوقعة لتوليد المفاتيح المستخدمة في بروتوكولات مثل بروتوكول أمان طبقة النقل (TLS).
مولدات الأرقام شبه العشوائية
البديل عن الأجهزة العتادية هو الخوارزميات؛ إذ ينتج مولد الأرقام شبه العشوائية (PRNG) تسلسلاً يبدو عشوائياً ظاهرياً، لكنه محدد كلياً بقيمة ابتدائية تُعرف باسم البذرة (seed). فإذا أعطيت البذرة نفسها للخوارزمية نفسها، فستحصل على نفس تسلسل الأرقام في كل مرة. ويُعد هذا نقطة ضعف حين تتطلب المهمة عدم إمكانية التنبؤ بالنتائج وتكون البذرة أو الحالة الداخلية قابلة للتخمين أو إعادة البناء، في حين يمثل ميزة قوية عندما تتطلب التجارب إمكانية تكرار النتائج بدقة — كما هو الحال في عمليات المحاكاة أو الاختبارات البرمجية. كما تتميز مولدات PRNG بكونها سريعة، واقتصادية، وسهلة التطبيق، ولهذا السبب تعتمد عليها معظم البرمجيات. ومن بين أبرز هذه الخوارزميات المولد الخطي المتطابق (LCG)، وخوارزميات xorshift، وخوارزمية ميرسين تويستر (Mersenne Twister).
خوارزمية ميرسين تويستر
نُشرت خوارزمية Mersenne Twister في عام 1997 على يد ماكوتو ماتسوموتو وتاكوجي نيشيمورا، وهي من أكثر مولدات الأرقام شبه العشوائية انتشاراً وتُعد الخيار الافتراضي في العديد من لغات البرمجة. ويشتق اسمها من دورة تكرارها — أي طول التسلسل قبل أن يبدأ في تكرار نفسه — والتي تبلغ في نسختها القياسية MT19937 عدد ميرسين الأولي 219937 − 1. تجتاز هذه الخوارزمية معظم الاختبارات الإحصائية للعشوائية وتناسب نماذج المحاكاة بامتياز. ومع ذلك، لم تُصمم لحفظ الأسرار الأمنية: فمن خلال مراقبة 624 قيمة متتالية بحجم 32 بت، يمكن لأي شخص إعادة بناء حالتها الداخلية بدقة والتنبؤ بجميع القيم التالية، لذا يجب ألا تُستخدم لتوليد مفاتيح التشفير أو كلمات المرور أو أي شيء يجب أن يبقى غير قابل للتنبؤ.
المولدات الآمنة تشفيرياً والإنتروبيا
تحتاج تطبيقات عديدة إلى ميزتين في آن واحد: سرعة الخوارزميات البرمجية، واستحالة التنبؤ التي توفرها المصادر الفيزيائية. والحل يكمن في مولد أرقام شبه عشوائية آمن تشفيرياً (CSPRNG). وهو يظل نوعاً من مولدات PRNG، لكنه مبني بطريقة تمنع أي شخص يرى جزءاً من قيمه من التنبؤ ببقية النتائج عملياً، كما يتم تزويده بالبذرة، وإعادة تزويده بانتظام، من مصدر إنتروبيا حقيقي. ولا تجعل البذرة المستمدة من مصدر فيزيائي مولد PRNG العادي آمناً تلقائياً؛ إذ يجب أن تكون الخوارزمية مصممة خصيصاً لذلك. يوفر المصدر الفيزيائي كالتشويش الحراري أو توقيت أحداث العتاد مقداراً يسيراً من العشوائية الحقيقية، ثم تستخرج منه خوارزمية CSPRNG سلسلة طويلة من القيم بمعدل أعلى بكثير. هذا المزيج هو ما يقدمه نظام التشغيل للبرامج التي تعمل عليه، وهو ما يُقصد به عادةً مصطلح "مولد الأرقام العشوائية" في التطبيقات العملية اليوم، حيث يُعتمد عليه لإنتاج مفاتيح التشفير، ورموز الجلسات، وكلمات المرور.
الأرقام العشوائية في المتصفح
توفر لغة JavaScript لصفحات الويب طريقتين مدمجتين للحصول على قيم عشوائية، وهما تنتميان إلى فئتين مختلفتين. الأولى هي Math.random()، وهي مولد PRNG عادي: يترك معيار اللغة تحديد خوارزميته لكل متصفح ولا يقدم أي ضمانات بشأن الأمان — وهو مناسب للرسوم المتحركة، لكنه غير ملائم على الإطلاق لإجراء سحب قد يعترض عليه أحد. أما الطريقة الأخرى فهي واجهة Web Crypto API. حيث توفر دالتها crypto.getRandomValues() قيماً عشوائية قوية تشفيرياً، ينتجها مولد CSPRNG يُغذى بإنتروبيا نظام التشغيل.
يعتمد مولد الأرقام العشوائية عبر الإنترنت الخاص بنا على واجهة Web Crypto API في كل سحب، وتتولد الأرقام في متصفحك بدلاً من خادم خارجي. والمصدر نفسه هو ما يدير باقي المولدات في هذا الموقع، سواء أردت أن ترمي النرد، أو ترمي العملة، أو تولد كلمة مرور.
تحويل البتات العشوائية إلى رقم في نطاقك المحدد
لا يمثل المولد الآمن تشفيرياً سوى نصف الخطوات المطلوبة لإجراء سحب عادل؛ فهو يقدم بتات خاماً، ويتعين على البرنامج بعد ذلك تحويلها إلى رقم يقع ضمن نطاقك المحدد — وهنا تحديداً قد يتسلل انحياز باقي القسمة وتفاوت الفرص. لنفترض أن المصدر يعطي القيم من 0 إلى 9 بفرص متساوية، بينما تحتاج أنت إلى رقم من 0 إلى 5. قد يبدو أخذ باقي القسمة بعد القسمة على 6 أمراً طبيعياً، لكن الأرقام 0 و1 و2 و3 يمكن أن تظهر حينئذ بطريقتين مختلفتين، بينما لا يظهر الرقمان 4 و5 إلا بطريقة واحدة؛ مما يمنح كلاً من الأرقام 0 إلى 3 فرصة بنسبة 20%، في حين لا يحصل كل من 4 و5 إلا على نسبة 10% فقط. ومن طرق إزالة هذا التحيز استبعاد القيم التي لا تتطابق وإعادة السحب من جديد؛ وهو ما توضحه بالتفصيل مواد الأرقام العشوائية.
هناك أمران آخران يثيران دهشة المستخدمين غالباً؛ أولهما أن التكرار أمر طبيعي: فعند سحب رقم صحيح من 1 إلى 10 بشكل مستقل وبفرص متساوية للجميع، تكون للرقم المسحوب للتو نفس فرصة الظهور مجدداً، وهي 1 من كل 10 مثل أي رقم آخر. فالسحب دون تكرار هو نوع مختلف من السحب، وليس سحباً أكثر عشوائية. وثانيهما أن المولد العادل وحده لا يجعل الإجراء بأكمله عادلاً: فقائمة المشاركين وعدد المحاولات لهما نفس الأهمية، كما يوضح ذلك مقالنا حول كيفية اختيار فائز عشوائي في مسابقة.