عشوائي | ببذرة | قابل للتكرار

> مولّد أرقام عشوائية <

// أنشئ أعدادًا صحيحة وعشرية عشوائية تشفيريًا — أو زوّدها ببذرة لعمليات تشغيل قابلة للتكرار

[CRYPTO]

عشوائية تشفيرية

يستخدم افتراضيًا crypto.getRandomValues() مع أخذ العينات بالرفض بحيث يكون كل عدد صحيح في نطاقك متساوي الاحتمال — دون أي انحياز للباقي القسمة.

[SEEDED]

وضع البذرة القابل للتكرار

زوّد أي سلسلة بذرة للتبديل إلى مولّد أرقام شبه عشوائية حتمي من نوع mulberry32. نفس البذرة، نفس الأرقام — مثالي للاختبارات والمحاكاة.

[NO-DUP]

وضع بدون تكرار

أنشئ أعدادًا صحيحة فريدة عبر أخذ العينات على أسلوب Fisher-Yates. رائع لسحوبات اليانصيب أو القرعات أو أخذ العينات دون إرجاع.

[DECIMALS]

التحكم في الدقة العشرية

بدّل إلى الوضع العشري واختر من 1 إلى 10 منازل. توزَّع الأرقام بانتظام عبر [الحد الأدنى، الحد الأقصى) وتُقرَّب إلى الدقة التي تختارها.

// حول إنشاء الأرقام العشوائية

كيف يعمل:

عندما يكون حقل البذرة فارغًا، تستدعي هذه الأداة crypto.getRandomValues(new Uint32Array(1))، وهو مولّد أرقام شبه عشوائية آمن تشفيريًا (CSPRNG) مدعوم بمجمّع الإنتروبيا في نظام تشغيلك. ولتعيين عدد صحيح غير موقّع بحجم 32 بت على نطاق [min, max] اعتباطي دون انحياز للباقي القسمة، يستخدم المولّد أخذ العينات بالرفض: يُرفض أي سحب يتجاوز أكبر مضاعف للنطاق يتسع ضمن 2^32 ثم يُعاد سحبه. وعندما تزوّد بذرة، تُجزَّأ السلسلة باستخدام cyrb53 إلى عدد صحيح بحجم 32 بت ثم تُغذَّى إلى mulberry32، وهو مولّد سريع بحجم 32 بت بدورة قدرها 2^32 — حتمي وقابل للتكرار. ويعمل الوضع العشري على تحجيم عينة منتظمة من [0,1) إلى [min, max)، ثم يُنسِّقها باستخدام toFixed(places).

مثال:

min=1, max=100, count=5, seed="hello" -> 39, 98, 64, 12, 71 (دائمًا)

المعايير والمراجع:

  • >Web Crypto API (W3C) — عقد crypto.getRandomValues() الخاص بمولّدات الأرقام شبه العشوائية الآمنة تشفيريًا
  • >RFC 4086 — Randomness Requirements for Security
  • >mulberry32 — مولّد أرقام شبه عشوائية بحجم 32 بت من تأليف Tommy Ettinger، ملكية عامة
  • >cyrb53 — تجزئة سلسلة سريعة بحجم 53 بت للبذر (bryc، ملكية عامة)

حالات الاستخدام الشائعة:

  • >سحوبات اليانصيب والقرعات باختيارات فريدة يمكن إثباتها
  • >أخذ عينات عشوائية دون إرجاع للاستطلاعات والتدقيقات
  • >محاكاة مونت كارلو والتجارب الإحصائية
  • >توزيع اختبار A/B بتعيينات قابلة للتكرار قائمة على البذرة
  • >آليات الألعاب: بدائل النرد، وجداول الغنائم، وبذور المراحل
  • >بيانات اختبار ضمان الجودة وإنشاء مدخلات الاختبار العشوائي (الفازِنغ)
  • >اختيار الفائزين أو الحكام أو أول المتحدثين في الاجتماعات
  • >إنشاء بيانات اصطناعية للنماذج الأولية والعروض التوضيحية

أدوات ذات صلة:

  • >مولّد UUID — معرّفات v4 عشوائية عندما تحتاج إلى معرّف فريد بدلًا من رقم
  • >مولّد كلمات المرور — سلاسل عشوائية تشفيريًا مع التحكم في مجموعة الأحرف
  • >مولّد BIP39 — عبارات بذرة تذكّرية عشوائية لمحافظ العملات المشفّرة
  • >randompickerwheel.app — واجهة عجلة دوّارة عندما تريد منتقيًا عشوائيًا مرئيًا لجمهور مباشر أو لصف دراسي للأطفال

// أمثلة على الإخراج

سحب يانصيب — 6 أرقام فريدة من 1-49

config: min=1, max=49, count=6, no-duplicates=on, sort=ascending

output:

7, 13, 22, 28, 35, 41

بديل النرد — عشر رميات d20 (التكرار مسموح)

config: min=1, max=20, count=10, no-duplicates=off, sort=none

output:

14, 3, 20, 11, 7, 14, 2, 19, 8, 11

أخذ عينات عشرية — 5 أعداد عائمة في [0, 1) بأربع منازل عشرية

config: type=decimal, min=0, max=1, count=5, places=4

output:

0.4172, 0.8635, 0.0291, 0.5508, 0.7723

قابل للتكرار ببذرة — نفس البذرة تُنتج نفس التسلسل

config: min=1, max=100, count=5, seed="hello" (شغّل مرتين)

output:

التشغيل 1: 39, 98, 64, 12, 71 / التشغيل 2: 39, 98, 64, 12, 71

التوزيع — 100 اختيار A/B مُرجَّح عبر باقي القسمة الصحيح

config: min=0, max=99, count=100, seed="experiment-42", sort=ascending

output:

0, 1, 3, 4, 7, 9, 12, ... 95, 97, 98, 99 (حتمي)

// نفّذه بنفسك

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

[JavaScript]

عدد صحيح آمن تشفيريًا في [min, max] (دون انحياز للباقي القسمة)

function secureRandomInt(min, max) {
  const range = max - min + 1;
  const buf = new Uint32Array(1);
  const max32 = 0xFFFFFFFF;
  const limit = Math.floor((max32 + 1) / range) * range;
  let v;
  do {
    crypto.getRandomValues(buf);
    v = buf[0];
  } while (v >= limit);
  return min + (v % range);
}
[JavaScript]

mulberry32 — مولّد أرقام شبه عشوائية حتمي مبذور (حالة 32 بت، دورة ~2^32)

function mulberry32(seed) {
  let a = seed >>> 0;
  return function () {
    a = (a + 0x6D2B79F5) | 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

// usage: const rng = mulberry32(0xC0FFEE);
//        rng(); // 0.6743..., reproducible across runs
[JavaScript]

cyrb53 — تجزئة سريعة من سلسلة إلى 32 بت (استخدمها لبذر mulberry32)

function cyrb53(str, seed) {
  seed = seed || 0;
  let h1 = 0xdeadbeef ^ seed;
  let h2 = 0x41c6ce57 ^ seed;
  for (let i = 0; i < str.length; i++) {
    const ch = str.charCodeAt(i);
    h1 = Math.imul(h1 ^ ch, 2654435761);
    h2 = Math.imul(h2 ^ ch, 1597334677);
  }
  h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
       Math.imul(h2 ^ (h2 >>> 13), 3266489909);
  h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
       Math.imul(h1 ^ (h1 >>> 13), 3266489909);
  return (h1 >>> 0);
}

// const rng = mulberry32(cyrb53('my-seed-string'));

// المزالق الشائعة

> انحياز باقي القسمة

إن Math.floor(Math.random() * range) البسيط يوزّع البتات العليا بشكل غير متساوٍ عندما لا يكون النطاق قوّة للعدد 2 — إذ تظهر بعض المخرجات بتواتر أعلى قليلًا من غيرها. استخدم أخذ العينات بالرفض (المقتطف أعلاه) لرفض السحوبات الخارجة عن النطاق والحفاظ على توزيع منتظم.

> Math.random() ليست آمنة تشفيريًا

تستخدم Math.random() في V8/Spidermonkey خوارزمية xorshift128+، وهي سريعة لكنها قابلة للتنبؤ: يمكن لمهاجم يرصد بضعة مخرجات أن يستعيد الحالة الداخلية ويتنبأ بالقيم المستقبلية. وللرموز المميّزة، والأملاح، وسحوبات اليانصيب الحرجة من حيث النزاهة، أو أي شيء يهتم به الخصم، استخدم دائمًا crypto.getRandomValues().

> مولّدات الأرقام شبه العشوائية المبذورة حتمية — لا تستخدمها أبدًا للأمان

صُمّمت mulberry32 وأمثالها لتتكرر. وهذا بالضبط ما تريده للاختبارات والمحاكاة والتوزيع — وبالضبط ما لا تريده لرموز إعادة تعيين كلمات المرور أو معرّفات الجلسات. وإذا وجدت نفسك تمرّر بذرة إلى أي شيء موجَّه للمستخدم أو قريب من المصادقة، فعُد فورًا إلى المولّد الآمن تشفيريًا.

> رفض التكرار عند العدد المرتفع يستنفد السعة

طلب k عددًا صحيحًا فريدًا من نطاق حجمه n حيث يقترب k من n يتحوّل إلى مسألة جامع القسائم: تصبح السحوبات القليلة الأخيرة باهظة أُسّيًا. تحدّ هذه الأداة العدد عند 10,000 وتستخدم أخذ عينات Fisher-Yates الجزئي بحيث تكون السعة دقيقة، لكن حلقة while بسيطة مع seen.has(x) ستتعلّق بصمت عندما يكون k > n. تحقّق دائمًا من السعة مسبقًا.

>> الأسئلة الشائعة

س: هل مولّد الأرقام العشوائية هذا آمن تشفيريًا؟

ج: نعم، افتراضيًا. عندما تترك حقل SEED فارغًا، تستخدم الأداة crypto.getRandomValues()، وهو المولّد الآمن تشفيريًا في Web Crypto API، الذي يقرأ على Linux/macOS من /dev/urandom وعلى Windows من BCryptGenRandom. كما نطبّق أخذ العينات بالرفض بحيث يكون التعيين من عدد صحيح بحجم 32 بت إلى نطاقك المخصّص غير منحاز. والإخراج مناسب للمهام القريبة من الأمان مثل إنشاء الرموز المميّزة، أو اختيار الأملاح، أو إجراء سحوبات يانصيب عادلة. لاحظ أن تزويد بذرة يبدّل إلى مولّد أرقام شبه عشوائية حتمي (mulberry32) ليس آمنًا تشفيريًا — استخدمه فقط عندما تكون قابلية التكرار أهم من السرّية.

س: ما الفرق بين الوضع المبذور والوضع غير المبذور؟

ج: يستخدم الوضع غير المبذور (الافتراضي) المولّد الآمن تشفيريًا في متصفحك، وينتج أرقامًا جديدة لا يمكن التنبؤ بها في كل نقرة — فلن يعيد الاستدعاء نفسه أبدًا التسلسل نفسه مرتين. أما الوضع المبذور فيجزّئ سلسلة البذرة إلى عدد صحيح بحجم 32 بت باستخدام cyrb53 ويغذّيها إلى mulberry32، وهو مولّد أرقام شبه عشوائية حتمي. فالبذرة المتطابقة مع الإعدادات المتطابقة تُنتج دائمًا التسلسل المتطابق، وهو أمر بالغ القيمة للتجارب القابلة للتكرار، وتنقيح الشيفرة العشوائية، ومشاركة تجهيزات الاختبار، أو توزيع اختبار A/B حيث يجب أن يقع كل مستخدم دائمًا في الدلو نفسه.

س: كيف يعمل خيار بدون تكرار؟

ج: بالنسبة إلى الأعداد الصحيحة، يسحب خيار بدون تكرار من النطاق [min..max] باستخدام خلط جزئي مستوحى من Fisher-Yates يُنتج أول k عنصرًا دون أي تكرار. ونستخدم خريطة تبديل متفرّقة بحيث يبقى استهلاك الذاكرة O(count) بدلًا من O(range)، مما يعني أن سحب 10 أرقام فريدة من 1 إلى 1,000,000 رخيص تمامًا مثل سحب 10 من 1 إلى 100. وإذا طلبت أرقامًا فريدة أكثر مما يستطيع النطاق توفيره (مثلًا 20 عددًا صحيحًا فريدًا في 1–10)، تُبلّغ الأداة عن خطأ سعة واضح بدلًا من التكرار إلى ما لا نهاية.

س: هل يمكنني إنشاء أرقام عشوائية عشرية (نقطة عائمة)؟

ج: نعم. اضبط زر TYPE على عشري واختر دقة بين 1 و10 منازل. يسحب المولّد عددًا عائمًا منتظمًا في [0, 1)، ويحجّمه إلى [min, max)، ثم يُقرّبه باستخدام toFixed(places) ويحلّله مرة أخرى إلى رقم. لاحظ أن max مستثنى في الوضع العشري (وهو أثر جانبي لكيفية تعريف انتظام النقطة العائمة). ولمعظم الاستخدامات الإحصائية تكفي 4–6 منازل عشرية بكثرة؛ أما العشر منازل فتقترب من حدّ الدقة المزدوجة IEEE 754 للنطاقات الصغيرة النموذجية.

س: هل هناك حدّ أقصى للعدد؟

ج: العدد محدود بـ 10,000 رقم لكل نقرة. وهذا يُبقي الصفحة سريعة الاستجابة على الهواتف ويتجنّب سلوك المتصفح في الحالات الحدّية مع مناطق النصوص الضخمة جدًا. وإذا كنت بحاجة إلى ملايين القيم، فشغّل عدّة دفعات ببذور مختلفة وادمج الإخراج، أو انسخ الخوارزمية إلى سكربت Node — فنفس زوج mulberry32 / cyrb53 يعمل على جانب الخادم أيضًا. ولأسباب تتعلق بتجربة المستخدم، يحدث الترتيب والنسخ والتنزيل جميعها على جانب العميل، لذا فإن 10 آلاف سقف معقول يكتمل مع ذلك في أقل بكثير من ميلي ثانية على حاسوب محمول حديث.

س: هل تُرفَع بياناتي إلى أي مكان؟

ج: لا. تعمل كل عملية في متصفحك بصيغة JavaScript خالصة: إنشاء الأرقام، والترتيب، والإحصاءات، والنسخ إلى الحافظة، وتنزيل ملف .txt. ولا يُرسَل أي طلب إلى خوادمنا عند النقر على GENERATE أو COPY أو DOWNLOAD — يمكنك التحقق من ذلك عبر تبويب الشبكة في متصفحك. ولا نسجّل البذور أو النطاقات أو المخرجات. والصفحة هي HTML ثابت يُقدَّم عبر HTTPS من شبكة توصيل محتوى، لذا لا يكون أي شيء عن مدخلاتك قابلًا للرصد من قِبَلنا إطلاقًا. وهذا يجعل الأداة آمنة لتجهيزات الاختبار السرّية، أو بذور اليانصيب الداخلية، أو أي شيء آخر تفضّل إبقاءه بعيدًا عن خوادم الأطراف الثالثة.

س: هل يمكنني تجنّب التكرار عند إنشاء الأرقام العشرية؟

ج: نعم، ينطبق مربع اختيار بدون تكرار على الأرقام العشرية أيضًا باستخدام حلقة إعادة محاولة بأفضل جهد ممكن. وبما أن عددين عائمين أُخذا بشكل مستقل لا يتصادمان أبدًا تقريبًا على مستوى البتات، فإن التكرارات نادرة ما لم يكن نطاقك صغيرًا جدًا مقارنة بالدقة (مثلًا، min=0, max=1, places=2 لا يملك سوى 100 قيمة متمايزة). وإذا تعذّر على الحلقة إيجاد ما يكفي من القيم الفريدة ضمن عدد معقول من المحاولات، تُبلّغ الأداة عن خطأ سعة كي تتمكّن من توسيع النطاق أو زيادة الدقة. وللأرقام العشرية المضمونة الفرادة بصرامة، يُفضَّل استخدام الوضع الصحيح وقسمة النتيجة بنفسك.

س: متى ينبغي أن أستخدم عجلة دوّارة بدلًا من قائمة أرقام؟

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

// OTHER LANGUAGES