<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Prime Numbers on kenji.blog</title><link>http://kenji.blog/ar/tags/prime-numbers/</link><description>Recent content in Prime Numbers on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ar</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 16:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ar/tags/prime-numbers/index.xml" rel="self" type="application/rss+xml"/><item><title>فرضية ريمان وتوزيع الأعداد الأولية: علاقة عميقة مع تقنيات التشفير الحديثة</title><link>http://kenji.blog/ar/p/riemann-hypothesis-prime-distribution-cryptography/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/riemann-hypothesis-prime-distribution-cryptography/</guid><description>&lt;img src="http://kenji.blog/p/riemann-hypothesis-prime-distribution-cryptography/img/eyecatch.jpg" alt="Featured image of post فرضية ريمان وتوزيع الأعداد الأولية: علاقة عميقة مع تقنيات التشفير الحديثة" />&lt;h1 id="1-مقدمة-غموض-الأعداد-الأولية-في-الكون-وفرضية-ريمان">1. مقدمة: غموض الأعداد الأولية في الكون وفرضية ريمان
&lt;/h1>&lt;p>&amp;ldquo;الأعداد الأولية (Prime Numbers)&amp;rdquo; هي الأعداد الطبيعية التي لا تقبل القسمة إلا على 1 وعلى نفسها، وتُعرف أيضاً بـ &amp;ldquo;ذرات&amp;rdquo; عالم الرياضيات. تبدو هذه السلسلة من الأعداد 2, 3, 5, 7, 11, 13&amp;hellip; عشوائية وبدون نظام واضح للوهلة الأولى. منذ أن أثبت عالم الرياضيات اليوناني القديم إقليدس أن &amp;ldquo;الأعداد الأولية لا نهائية&amp;rdquo;، حاول عدد لا يحصى من علماء الرياضيات كشف القواعد الخفية وراء تسلسل هذه الأعداد.&lt;/p>
&lt;p>أقرب محاولة لحل لغز الأعداد الأولية كانت &lt;strong>&amp;ldquo;فرضية ريمان (Riemann Hypothesis)&amp;rdquo;&lt;/strong> التي اقترحها عالم الرياضيات الألماني برنارد ريمان (Bernhard Riemann) في عام 1859. تعتبر فرضية ريمان واحدة من أهم المسائل المستعصية في الرياضيات الحديثة، وهي إحدى مسائل جائزة الألفية التي حددها معهد كلاي للرياضيات بجائزة قدرها مليون دولار.&lt;/p>
&lt;p>للوهلة الأولى، قد يبدو لغز التوزيع للأعداد الأولية في الرياضيات البحتة غير ذي صلة بحياتنا اليومية. ومع ذلك، فإن أمن الإنترنت الذي يدعم البنية التحتية للمجتمع الحديث، وخاصة &lt;strong>تقنيات التشفير الحديثة مثل تشفير RSA وتشفير المنحنيات الإهليلجية (ECC)&lt;/strong>، يعتمد بشدة على خصائص الأعداد الأولية الضخمة.&lt;/p>
&lt;p>في هذا المقال، سنقوم برحلة رياضية من توزيع الأعداد الأولية إلى مبرهنة الأعداد الأولية، ودالة زيتا لريمان، وصولاً إلى جوهر فرضية ريمان، وسنتعمق بالتفصيل في كيفية ارتباطها بتقنيات التشفير الحديثة، وماذا سيحدث للعالم إذا تم إثبات فرضية ريمان.&lt;/p>
&lt;hr>
&lt;h1 id="2-مبرهنة-الأعداد-الأولية-وتوزيع-الأعداد-الأولية-اكتشاف-غاوس">2. مبرهنة الأعداد الأولية وتوزيع الأعداد الأولية: اكتشاف غاوس
&lt;/h1>&lt;p>لفهم كيفية توزيع الأعداد الأولية، فكر علماء الرياضيات في &lt;strong>دالة عد الأعداد الأولية (Prime-counting function)&lt;/strong> $\pi(x)$ التي تعبر عن &amp;ldquo;عدد الأعداد الأولية الموجودة أقل من أو تساوي عدداً معيناً $x$&amp;rdquo;.&lt;/p>
&lt;p>على سبيل المثال:&lt;/p>
&lt;ul>
&lt;li>$\pi(10) = 4$ (2, 3, 5, 7)&lt;/li>
&lt;li>$\pi(100) = 25$&lt;/li>
&lt;li>$\pi(1000) = 168$&lt;/li>
&lt;/ul>
&lt;p>اكتشف عالم الرياضيات العبقري كارل فريدريش غاوس (Carl Friedrich Gauss) في سن الخامسة عشرة، بعد حساب جداول ضخمة للأعداد الأولية، أن تكرار ظهور الأعداد الأولية يتناقص بشكل يتناسب عكسياً مع اللوغاريتم الطبيعي $\ln x$. بمعنى آخر، توقع أن احتمال العثور على عدد أولي بالقرب من عدد معين $x$ هو حوالي $\frac{1}{\ln x}$.&lt;/p>
&lt;p>تم التعبير عن هذا باستخدام التكامل في &lt;strong>التكامل اللوغاريتمي (Logarithmic integral)&lt;/strong> $\text{Li}(x)$:&lt;/p>
$$ \text{Li}(x) = \int_{2}^{x} \frac{dt}{\ln t} $$
&lt;p>تم إثبات توقع غاوس لاحقاً وبشكل مستقل من قبل جاك هادامار وشارل جان دو لا فالي بوسان في عام 1896، وتأسست كـ &lt;strong>مبرهنة الأعداد الأولية (Prime Number Theorem, PNT)&lt;/strong>:&lt;/p>
$$ \lim_{x \to \infty} \frac{\pi(x)}{\text{Li}(x)} = 1 $$
&lt;p>أو يمكن التعبير عنها تقريبياً على النحو التالي:&lt;/p>
$$ \pi(x) \sim \frac{x}{\ln x} $$
&lt;p>بفضل هذه المبرهنة، أصبح من الواضح أن الأعداد الأولية، عند النظر إليها على نطاق واسع (ماكروسكوبي)، تمتلك توزيعاً سلساً للغاية ويمكن التنبؤ به. ومع ذلك، عند النظر إليها على نطاق ضيق (ميكروسكوبي)، هناك دائماً &amp;ldquo;خطأ&amp;rdquo; أو &amp;ldquo;تذبذب&amp;rdquo; بين $\pi(x)$ و $\text{Li}(x)$. الهوية الحقيقية لهذا التذبذب هي اللغز الأكبر الذي تحاول فرضية ريمان حله.&lt;/p>
&lt;hr>
&lt;h1 id="3-دالة-زيتا-لريمان-وحاصل-ضرب-أويلر">3. دالة زيتا لريمان وحاصل ضرب أويلر
&lt;/h1>&lt;p>أقوى سلاح في تحليل توزيع الأعداد الأولية هو &lt;strong>دالة زيتا لريمان (Riemann Zeta Function)&lt;/strong>. في الأصل، كانت متسلسلة لانهائية تم تعريفها من قبل ليونهارت أويلر (Leonhard Euler) للأعداد الحقيقية $s > 1$:&lt;/p>
$$ \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s} = 1 + \frac{1}{2^s} + \frac{1}{3^s} + \frac{1}{4^s} + \dots $$
&lt;p>أحد أعظم إنجازات أويلر هو إثباته أن هذه المتسلسلة اللانهائية يمكن التعبير عنها كحاصل ضرب لانهائي يشمل جميع الأعداد الأولية $p$. هذا هو &lt;strong>حاصل ضرب أويلر (Euler Product Formula)&lt;/strong>:&lt;/p>
$$ \zeta(s) = \prod_{p \text{ prime}} \frac{1}{1 - p^{-s}} = \left( \frac{1}{1 - 2^{-s}} \right) \left( \frac{1}{1 - 3^{-s}} \right) \left( \frac{1}{1 - 5^{-s}} \right) \dots $$
&lt;p>الفهم الحدسي لهذا الإثبات هو أنه إذا قمنا بنشر كل حد في الجانب الأيمن كمتسلسلة هندسية وضربناها معاً، فبفضل المبرهنة الأساسية في الحساب (كل عدد طبيعي يمكن التعبير عنه بشكل فريد كحاصل ضرب أعداد أولية)، يتم إعادة بناء مجموع مقلوبات الأعداد الطبيعية في الجانب الأيسر بالكامل.&lt;/p>
&lt;p>&lt;strong>هذه المعادلة الرياضية الواحدة أصبحت جسراً يربط بين التحليل الرياضي (المتسلسلات اللانهائية والدوال المستمرة) ونظرية الأعداد (الأعداد الأولية والأعداد المنفصلة).&lt;/strong> دراسة دالة زيتا مرادفة لدراسة توزيع الأعداد الأولية.&lt;/p>
&lt;hr>
&lt;h1 id="4-الامتداد-التحليلي-والتوسيع-إلى-المستوى-المركب">4. الامتداد التحليلي والتوسيع إلى المستوى المركب
&lt;/h1>&lt;p>تكمن عبقرية ريمان في أنه وسع المتغير $s$ في الدالة $\zeta(s)$، الذي كان أويلر يعتبره عدداً حقيقياً فقط، ليصبح &lt;strong>عدداً مركباً $s = \sigma + it$ ($\sigma$ هو الجزء الحقيقي و $t$ هو الجزء التخيلي)&lt;/strong>.&lt;/p>
&lt;p>المتسلسلة اللانهائية الأصلية تتقارب فقط عندما يكون $\sigma > 1$، ولكن باستخدام تقنية &amp;ldquo;الامتداد التحليلي (Analytic Continuation)&amp;quot;، وسع ريمان التعريف بحيث أصبح للدالة $\zeta(s)$ معنى في كل المستوى المركب باستثناء القطب عند $s = 1$.&lt;/p>
&lt;p>وعلاوة على ذلك، استنتج معادلة دالية (Functional equation) جميلة تحققها دالة زيتا:&lt;/p>
$$ \zeta(s) = 2^s \pi^{s-1} \sin\left(\frac{\pi s}{2}\right) \Gamma(1-s) \zeta(1-s) $$
&lt;p>حيث $\Gamma(x)$ هي دالة غاما. من خلال هذه المعادلة، يمكننا معرفة خصائص النصف الأيسر من المستوى بناءً على خصائص النصف الأيمن.&lt;/p>
&lt;h3 id="الأصفار-zeros-of-the-zeta-function">الأصفار (Zeros of the Zeta Function)
&lt;/h3>&lt;p>تُسمى الأعداد المركبة $s$ التي تجعل قيمة دالة زيتا تساوي 0 بـ &amp;ldquo;الأصفار&amp;rdquo;.
من المعادلة الدالية، عندما يكون $s$ عدداً زوجياً سالباً ($-2, -4, -6, \dots$)، تصبح $\sin(\pi s / 2)$ صفراً، وبالتالي تكون $\zeta(s) = 0$. وتُعرف هذه بـ &lt;strong>الأصفار البديهية (Trivial zeros)&lt;/strong>.&lt;/p>
&lt;p>ومع ذلك، ما يهم في توزيع الأعداد الأولية هي الأصفار الأخرى، وتحديداً &lt;strong>الأصفار غير البديهية (Non-trivial zeros)&lt;/strong> التي تقع في &amp;ldquo;الشريط الحرج (Critical strip)&amp;rdquo; حيث $0 \le \sigma \le 1$.&lt;/p>
&lt;hr>
&lt;h1 id="5-جوهر-فرضية-ريمان-والصيغة-الصريحة">5. جوهر فرضية ريمان والصيغة الصريحة
&lt;/h1>&lt;p>حسب ريمان عدداً قليلاً من الأصفار وطرح فرضية مذهلة. هذه هي &lt;strong>فرضية ريمان&lt;/strong>.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>فرضية ريمان (Riemann Hypothesis)&lt;/strong>
جميع الأصفار غير البديهية لدالة زيتا لريمان $\zeta(s)$ تقع على خط مستقيم جزؤه الحقيقي يساوي $1/2$ (أي $\text{Re}(s) = 1/2$).&lt;/p>
&lt;/blockquote>
&lt;p>يسمى هذا الخط الذي يكون فيه الجزء الحقيقي 1/2 بـ &amp;ldquo;الخط الحرج (Critical line)&amp;rdquo;.&lt;/p>
&lt;div class="mermaid">graph TD
A["دالة زيتا لريمان ζ(s)"] --> B["التوسيع إلى المستوى المركب بواسطة الامتداد التحليلي"]
B --> C["الأصفار البديهية (s = -2, -4, -6 ...)"]
B --> D["الأصفار غير البديهية (0 &lt;= Re(s) &lt;= 1)"]
D --> E["فرضية ريمان"]
E --> F["جميع الأصفار غير البديهية تقع على Re(s) = 1/2"]
F --> G["تؤدي إلى إثبات نهاية مصطلح الخطأ في توزيع الأعداد الأولية"]&lt;/div>
&lt;p>لماذا تعتبر فرضية ريمان على هذا القدر من الأهمية؟ لأن أصفار دالة زيتا تحدد &lt;strong>بالكامل&lt;/strong> توزيع الأعداد الأولية.&lt;/p>
&lt;p>استنتج ريمان ولاحقاً عالم الرياضيات فون مانجولدت &amp;ldquo;الصيغة الصريحة (Explicit formula)&amp;rdquo; التي تصف توزيع الأعداد الأولية بدقة. باستخدام دالة تشيبيشيف $\psi(x)$، يمكن التعبير عنها كما يلي:&lt;/p>
$$ \psi(x) = x - \sum_{\rho} \frac{x^\rho}{\rho} - \ln(2\pi) - \frac{1}{2}\ln(1 - x^{-2}) $$
&lt;p>حيث $\rho$ يمثل المجموع عبر جميع الأصفار غير البديهية لدالة زيتا.
المصطلح الرئيسي هو $x$ (والذي يتوافق مع مبرهنة الأعداد الأولية)، ومن خلال إضافة أو طرح المصطلحات الشبيهة بالتموجات التي تعتمد على الأصفار $\rho$، يتم إعادة بناء التوزيع الدقيق المتدرج للأعداد الأولية. يمكن القول إن الأصفار غير البديهية تمثل &amp;ldquo;ترددات (موجات)&amp;rdquo; توزيع الأعداد الأولية.&lt;/p>
&lt;p>إذا كانت فرضية ريمان صحيحة، وكان الجزء الحقيقي لجميع الأصفار غير البديهية $\rho$ هو بالضبط $1/2$، فإن مصطلح الخطأ في مبرهنة الأعداد الأولية سيندرج ضمن أصغر نطاق يمكن تصوره نظرياً.&lt;/p>
$$ |\pi(x) - \text{Li}(x)| \le \frac{1}{8\pi} \sqrt{x} \ln x \quad \text{for} \quad x \ge 2657 $$
&lt;p>بعبارة أخرى، &lt;strong>إذا كانت فرضية ريمان صحيحة، فسيثبت ذلك أن الأعداد الأولية موزعة بأكثر الطرق &amp;ldquo;انتظاماً وجمالاً&amp;rdquo; التي يمكننا تخيلها&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="6-العلاقة-التي-لا-تنفصل-بين-تقنيات-التشفير-الحديثة-والأعداد-الأولية">6. العلاقة التي لا تنفصل بين تقنيات التشفير الحديثة والأعداد الأولية
&lt;/h1>&lt;p>حتى هذه النقطة كنا في عالم الرياضيات البحتة العميق، ولكن هذه الخصائص للأعداد الأولية تدعم من الأساس مجتمعنا الرقمي الحديث. والمثال الأبرز على ذلك هو تشفير المفتاح العام مثل &lt;strong>تشفير RSA&lt;/strong>.&lt;/p>
&lt;p>تعتمد أمان كافة الاتصالات مثل مدفوعات بطاقات الائتمان على الإنترنت، وإرسال كلمات المرور، والتوقيعات الإلكترونية لتقنية البلوك تشين على &amp;ldquo;الأعداد الأولية&amp;rdquo;.&lt;/p>
&lt;h3 id="كيفية-عمل-تشفير-rsa">كيفية عمل تشفير RSA
&lt;/h3>&lt;p>يعتمد أمان تشفير RSA على الحقيقة الرياضية القائلة بأن &amp;ldquo;تحليل رقم مركب كبير جداً إلى عوامله الأولية يمثل صعوبة بالغة&amp;rdquo; (مسألة التحليل إلى العوامل الأولية).&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>توليد المفاتيح&lt;/strong>:
يتم اختيار عددين أوليين ضخمين بشكل عشوائي $p$ و $q$ (مثلاً 2048 بت لكل منهما).
يتم ضربهما معاً لحساب $N = p \times q$. هذا الـ $N$ يصبح جزءاً من المفتاح العام.
باستخدام دالة مؤشر أويلر $\phi(N) = (p-1)(q-1)$، يتم توليد المفتاح الخاص $d$.&lt;/p>
$$ e \times d \equiv 1 \pmod{\phi(N)} $$
&lt;/li>
&lt;li>
&lt;p>&lt;strong>التشفير وفك التشفير&lt;/strong>:
يتم تحويل النص الواضح $M$ إلى نص مشفر $C$ باستخدام المفتاح العام $e, N$.
&lt;/p>
$$ C \equiv M^e \pmod{N} $$
&lt;p>
فقط من يمتلك المفتاح الخاص $d$ يمكنه فك التشفير.
&lt;/p>
$$ M \equiv C^d \pmod{N} $$
&lt;/li>
&lt;/ol>
&lt;div class="mermaid">graph LR
A["النص الواضح (Plaintext)"] --> B["التشفير بالمفتاح العام (e, N)"]
B --> C["النص المشفر (Ciphertext)"]
C --> D["فك التشفير بالمفتاح الخاص (d)"]
D --> E["النص الواضح الأصلي"]
F["المهاجم (Attacker)"] -- "محاولة تحليل N إلى عوامله الأولية" --> C
F -.-> G["بدون معرفة p و q، لا يمكن حساب d"]&lt;/div>
&lt;p>لكسر تشفير RSA، من الضروري إيجاد الأعداد الأولية الأصلية $p$ و $q$ (التحليل إلى عوامل) انطلاقاً من العدد الضخم $N$. حتى باستخدام الخوارزميات السائدة حالياً (مثل منخل حقل الأعداد العام: GNFS)، فإن تحليل عدد يتكون من مئات الأرقام قد يستغرق وقتاً يتجاوز بكثير عمر الكون، حتى باستخدام أجهزة الكمبيوتر الفائقة.&lt;/p>
&lt;hr>
&lt;h1 id="7-تأثير-فرضية-ريمان-على-تقنيات-التشفير">7. تأثير فرضية ريمان على تقنيات التشفير
&lt;/h1>&lt;p>إذن، كيف تتقاطع &amp;ldquo;فرضية ريمان&amp;rdquo; الموجودة في قمة الرياضيات البحتة مع &amp;ldquo;تقنيات التشفير&amp;rdquo;؟&lt;/p>
&lt;h3 id="71-خوارزميات-توليد-الأعداد-الأولية-اختبار-الأولية-وفرضية-ريمان-المعممة-grh">7.1. خوارزميات توليد الأعداد الأولية (اختبار الأولية) وفرضية ريمان المعممة (GRH)
&lt;/h3>&lt;p>لتشغيل تشفير RSA، يجب أولاً توليد أعداد أولية ضخمة $p$ و $q$. ومع ذلك، فإن التحديد السريع والمؤكد لـ &amp;ldquo;ما إذا كان عدد ما أولياً أم لا&amp;rdquo; ليس أمراً سهلاً.&lt;/p>
&lt;p>حالياً، تستخدم الخوارزمية الاحتمالية المعروفة بـ &lt;strong>اختبار ميلر-رابين لأولية عدد (Miller-Rabin primality test)&lt;/strong> بشكل عملي. هذه الخوارزمية سريعة جداً، ولكنها تحمل خطراً ضئيلاً جداً لحدوث &amp;ldquo;أعداد شبه أولية&amp;rdquo;، حيث يتم تحديد عدد مركب بشكل خاطئ على أنه عدد أولي.&lt;/p>
&lt;p>ومع ذلك، إذا افترضنا أن &lt;strong>&amp;ldquo;فرضية ريمان المعممة (Generalized Riemann Hypothesis, GRH)&amp;rdquo;&lt;/strong>، التي توسع فرضية ريمان إلى دوال L لدركليه، صحيحة، فإن القصة تتغير بشكل جذري.
إذا كانت GRH صحيحة، فإن الحد الأقصى لعدد الاختبارات في خوارزمية ميلر-رابين يصبح مضموناً رياضياً، وترتقي من خوارزمية احتمالية إلى &lt;strong>&amp;ldquo;خوارزمية حتمية ذات وقت كثير الحدود&amp;rdquo;&lt;/strong> (كانت هذه حقيقة مهمة معروفة قبل اكتشاف اختبار AKS للأولية).&lt;/p>
&lt;p>بمعنى آخر، تلعب فرضية ريمان (وتعميماتها) دوراً في إعطاء ضمانات مباشرة وقاطعة لتوليد الأعداد الأولية الضخمة بسرعة وموثوقية مطلقة، وهو ما يمثل الأساس لتوليد التشفير.&lt;/p>
&lt;h3 id="72-العلاقة-بخوارزميات-التحليل-إلى-العوامل">7.2. العلاقة بخوارزميات التحليل إلى العوامل
&lt;/h3>&lt;p>تعتبر معرفة توزيع الأعداد الأولية أمراً حتمياً عند تقييم التعقيد الحسابي للخوارزميات المستخدمة لفك التشفير (مثل منخل حقل الأعداد العام). تعتمد العديد من خوارزميات التحليل إلى عوامل على توزيع &amp;ldquo;الأعداد السلسة (Smooth numbers: الأعداد التي تحتوي فقط على عوامل أولية صغيرة)&amp;rdquo;.&lt;/p>
&lt;p>لتقييم مدى تكرار ظهور الأعداد السلسة بدقة، يلزم وجود فهم عميق لتوزيع الأعداد الأولية، وهنا أيضاً يتم استخدام تقنيات نظرية الأعداد التحليلية المرتبطة مباشرة بدالة زيتا وفرضية ريمان. إذا تم إثبات فرضية ريمان وتم تحديد خطأ توزيع الأعداد الأولية بالكامل، فسيصبح من الممكن تحديد حدود الأداء لخوارزميات التحليل إلى عوامل بشكل أكثر دقة.&lt;/p>
&lt;hr>
&lt;h1 id="8-إذا-تم-إثبات-فرضية-ريمان-هل-سيتم-كسر-التشفير">8. إذا تم إثبات فرضية ريمان، هل سيتم كسر التشفير؟
&lt;/h1>&lt;p>غالباً ما يُقال كنوع من الأساطير الحضرية: &amp;ldquo;إذا حُلت فرضية ريمان، سينهار تشفير RSA في لحظة&amp;rdquo;، ولكن &lt;strong>هذا غير دقيق رياضياً&lt;/strong>.&lt;/p>
&lt;p>إثبات فرضية ريمان بحد ذاته لا يخلق فوراً خوارزمية سحرية تسرع بشكل كبير من التحليل إلى عوامل أولية. فرضية ريمان هي مجرد نظرية حول &amp;ldquo;الانتظام الماكروسكوبي لتوزيع&amp;rdquo; الأعداد الأولية، ولا تخبرنا مباشرة (كخاصية محلية) عن الأعداد الأولية التي تقسم عدداً معيناً $N$.&lt;/p>
&lt;p>ومع ذلك، فإن التأثير ليس صفراً.
لأنه في عملية إثبات فرضية ريمان، هناك احتمال كبير جداً لاكتشاف &lt;strong>&amp;ldquo;أدوات رياضية جديدة&amp;rdquo; أو &amp;ldquo;أساليب تحليل غير معروفة&amp;rdquo;&lt;/strong>. بالنظر إلى التاريخ، عندما تم إثبات مبرهنة فيرما الأخيرة أو حدسية بوانكاريه، فإن النظريات الجديدة التي طُورت خلال تلك العملية دفعت الرياضيات بأكملها إلى قفزات هائلة.&lt;/p>
&lt;p>إذا تم تأسيس طرق هندسية جبرية غير معروفة أو أساليب هندسية غير تبادلية قادرة على التحكم الكامل في خصائص أصفار دالة زيتا لريمان، فلا يمكن إنكار احتمال أن يؤدي ذلك كنتيجة إلى اكتشاف خوارزميات ثورية للتحليل إلى العوامل (على سبيل المثال، خوارزمية كلاسيكية تقلل وقت الحساب إلى وقت كثير الحدود). بهذا المعنى، لا يمكن لعلماء التشفير أن يغضوا الطرف أبداً عن تطورات فرضية ريمان.&lt;/p>
&lt;h3 id="الحواسيب-الكمومية-وخوارزمية-شور">الحواسيب الكمومية وخوارزمية شور
&lt;/h3>&lt;p>التهديد الأكثر مباشرة وواقعية لتقنيات التشفير ليس إثبات فرضية ريمان، بل &lt;strong>الحواسيب الكمومية&lt;/strong>. &amp;ldquo;خوارزمية شور&amp;rdquo; التي نشرها بيتر شور (Peter Shor) في عام 1994، أثبتت أنه بوجود حاسوب كمي ذو أداء كافٍ، يمكن حل التحليل إلى العوامل في وقت كثير الحدود. هذا يعني أن تشفير RSA وتشفير المنحنيات الإهليلجية سيتم كسرهما بشكل جذري.&lt;/p>
&lt;p>حالياً، يجري التحول عالمياً نحو &amp;ldquo;تشفير ما بعد الكوانتم (Post-Quantum Cryptography, PQC)&amp;rdquo; الذي لا يمكن فك تشفيره حتى بواسطة الحواسيب الكمومية (مثل التشفير القائم على الشبكات). ربما يقترب العصر الذهبي لتقنيات التشفير المعتمدة على الأعداد الأولية من نهايته بطريقة ما، لكن القيمة الرياضية للأعداد الأولية بحد ذاتها لن تضيع أبداً.&lt;/p>
&lt;hr>
&lt;h1 id="9-الخاتمة-تقاطع-التجريد-الرياضي-مع-المجتمع-الواقعي">9. الخاتمة: تقاطع التجريد الرياضي مع المجتمع الواقعي
&lt;/h1>&lt;div class="mermaid">graph TD
A["استكشاف الرياضيات البحتة"] --> B["توضيح فرضية ريمان"]
B --> C["فهم كامل لتوزيع الأعداد الأولية"]
C --> D["تطور هائل في نظرية الأعداد والهندسة الجبرية"]
D -.-> E["إمكانية خوارزميات جديدة للتحليل إلى العوامل"]
E -.-> F["تحديث تقييم أمان تقنيات التشفير"]
A --> G["الرياضيات التطبيقية وعلوم الكمبيوتر"]
G --> H["تحسين كفاءة اختبار الأولية وتوليد التشفير"]
H --> F&lt;/div>
&lt;p>الاستكشاف اللانهائي للأعداد الأولية، والذي استمر منذ اليونان القديمة، ارتقى بفضل العبقري ريمان ليصبح سيمفونية جميلة على المستوى المركب (أصفار دالة زيتا). ومن المثير للدهشة أن هذه البلورة الرياضية النقية، بعد مرور قرون، تُستخدم كأقوى درع لضمان أمن مجتمع الإنترنت.&lt;/p>
&lt;p>فرضية ريمان هي رمز يجسد في وقت واحد &amp;ldquo;الجمال التجريدي&amp;rdquo; للرياضيات و &amp;ldquo;القدرة المذهلة على التطبيق في العالم المادي والمجتمع الواقعي&amp;rdquo;.&lt;/p>
&lt;p>عندما يتم قهر هذا الجبل الرياضي الضخم الذي لم يصل إلى قمته أحد بعد، سنفهم تماماً الحقيقة الكونية المتمثلة في الأعداد الأولية، وسنمتلك منظوراً جديداً لبنية مجتمع المعلومات. إن دراسة تقنيات التشفير هي، في حد ذاتها، رحلة لتتبع تاريخ حكمة البشرية.&lt;/p></description></item><item><title>خوارزمية سريعة لاختبار الأولية مطبقة بلغة C++ (مثل طريقة Miller-Rabin)</title><link>http://kenji.blog/ar/p/cpp-fast-prime-testing-miller-rabin/</link><pubDate>Fri, 11 Sep 2026 14:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/cpp-fast-prime-testing-miller-rabin/</guid><description>&lt;img src="http://kenji.blog/p/cpp-fast-prime-testing-miller-rabin/img/eyecatch.jpg" alt="Featured image of post خوارزمية سريعة لاختبار الأولية مطبقة بلغة C++ (مثل طريقة Miller-Rabin)" />&lt;h1 id="مقدمة-لماذا-نحتاج-إلى-خوارزمية-سريعة-لاختبار-الأولية">مقدمة: لماذا نحتاج إلى خوارزمية سريعة لاختبار الأولية؟
&lt;/h1>&lt;p>في عالم علوم الحاسوب، ونظرية التشفير، أو البرمجة التنافسية، يعتبر التحديد السريع والدقيق لـ &amp;ldquo;ما إذا كان عدد ما أولياً أم لا&amp;rdquo; تحدياً أساسياً وهاماً جداً. على سبيل المثال، يعتمد أمان أنظمة تشفير المفتاح العام مثل تشفير RSA - والذي يمثل الأساس الأمني لمجتمع الإنترنت الحديث - على توليد أعداد أولية ضخمة وصعوبة ضربها (صعوبة تحليل العوامل الأولية). لذلك، ليس من المبالغة القول إن تقنية التمييز الفوري لما إذا كان عدد ضخم أولياً أم لا هي تقنية تدعم أساس المجتمع الرقمي.&lt;/p>
&lt;p>بالإضافة إلى ذلك، في البرمجة التنافسية (مثل AtCoder و Codeforces)، يعتبر اختبار الأولية موضوعاً متكرراً. بالنسبة للمدخلات الضخمة التي قد تصل إلى $N \le 10^{18}$، في الحالات التي يتم فيها إجراء اختبارات الأولية عشرات الآلاف من المرات في غضون ثانية واحدة، لا يمكن للخوارزميات التقليدية البسيطة أن تلبي متطلبات وقت الحساب وتتسبب في (Time Limit Exceeded: TLE).&lt;/p>
&lt;p>في هذا المقال، سنبدأ بخوارزمية اختبار الأولية البسيطة، ثم &amp;ldquo;اختبار فيرما&amp;rdquo; وهو اختبار احتمالي، وصولاً إلى الخوارزمية الأسرع والأكثر عملية &amp;ldquo;طريقة ميلر-رابين لاختبار الأولية (Miller-Rabin Primality Test)&amp;rdquo; التي تغلبت على نقاط الضعف في الخوارزميات السابقة. سنشرح ذلك بالتفصيل من الخلفية الرياضية إلى التنفيذ عالي التحسين بلغة C++. بشكل خاص، بالنسبة للأعداد الصحيحة بحجم 64 بت ($N &lt; 2^{64}$)، سنشرح بالتفصيل طريقة &amp;ldquo;تحديد الأولية بنسبة 100% (الاختبار الحتمي)&amp;rdquo; بدلاً من مجرد التحديد الاحتمالي، وسنوفر كود مصدري بلغة C++ جاهز للاستخدام العملي.&lt;/p>
&lt;hr>
&lt;h1 id="1-أساسيات-اختبار-الأولية-وطريقة-القسمة-التجريبية-trial-division">1. أساسيات اختبار الأولية وطريقة القسمة التجريبية (Trial Division)
&lt;/h1>&lt;p>العدد الأولي (Prime number) هو عدد طبيعي أكبر من أو يساوي 2، وليس له أي قواسم موجبة سوى 1 والعدد نفسه. باتباع تعريف العدد الأولي بدقة، لتحديد ما إذا كان العدد الصحيح $N$ أولياً، يمكننا محاولة قسمة $N$ على جميع الأعداد الصحيحة من $2$ إلى $N-1$. إذا لم يقبل القسمة على أي منها فهو عدد أولي، وإذا قَبِل القسمة ولو لمرة واحدة فهو عدد مؤلف (ليس أولياً).&lt;/p>
&lt;p>ولكن، تعقيد الوقت لهذه الطريقة هو $O(N)$، وإذا كان $N$ عدداً ضخماً مثل $10^{18}$، فسيستغرق الأمر وقتاً هائلاً لحسابه حتى مع أجهزة الكمبيوتر الحديثة.&lt;/p>
&lt;h2 id="تحسين-طريقة-القسمة-التجريبية-البحث-حتى-sqrtn">تحسين طريقة القسمة التجريبية: البحث حتى $\sqrt{N}$
&lt;/h2>&lt;p>عندما يتم التعبير عن العدد المؤلف $N$ كـ $a \times b = N$ (حيث $a \le b$)، فمن المؤكد أن $a \le \sqrt{N}$. لذلك، لا توجد حاجة لتكرار حلقة اختبار الأولية حتى $N-1$، ويكفي التحقق حتى $\sqrt{N}$.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// اختبار الأولية باستخدام طريقة القسمة التجريبية (O(sqrt(N)))
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">bool&lt;/span> &lt;span class="nf">is_prime_trial_division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// فحص الأعداد الفردية فقط من 3 فصاعداً
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>التعقيد الزمني لهذه الخوارزمية هو $O(\sqrt{N})$. إذا كان $N \le 10^{12}$ تقريباً، فيمكن حسابه في لحظة، ولكن في حالة $N \approx 10^{18}$، يصبح عدد التكرارات حوالي $10^9$ مرة، وحتى مع مترجمات C++، سيستغرق ذلك من مئات الميلي ثانية إلى عدة ثوانٍ، مما يجعله غير مناسب للاختبارات المتعددة.&lt;/p>
&lt;hr>
&lt;h1 id="2-اختبار-فيرما-بداية-اختبارات-الأولية-الاحتمالية">2. اختبار فيرما: بداية اختبارات الأولية الاحتمالية
&lt;/h1>&lt;p>لتجاوز حدود طريقة القسمة التجريبية، تم ابتكار &amp;ldquo;الخوارزميات الاحتمالية (Probabilistic Algorithm)&amp;rdquo; باستخدام نظريات من نظرية الأعداد. والمثال النموذجي لذلك هو &amp;ldquo;اختبار فيرما للأولية (Fermat Primality Test)&amp;rdquo; الذي يستخدم مبرهنة فيرما الصغرى.&lt;/p>
&lt;h2 id="مبرهنة-فيرما-الصغرى-fermats-little-theorem">مبرهنة فيرما الصغرى (Fermat&amp;rsquo;s Little Theorem)
&lt;/h2>&lt;p>اكتشف بيير دي فيرما (Pierre de Fermat) هذه النظرية، والتي تنص على ما يلي:&lt;/p>
&lt;blockquote>
&lt;p>لأي عدد أولي $p$، ولأي عدد صحيح $a$ أولي نسبياً مع $p$ (أي ليس من مضاعفات $p$)، تتحقق معادلة التطابق التالية:
&lt;/p>
$$ a^{p-1} \equiv 1 \pmod p $$
&lt;/blockquote>
&lt;p>إذا أخذنا المعاكس الإيجابي لهذه النظرية، فيمكننا القول: &amp;ldquo;بالنسبة لعدد صحيح $N$، وعدد صحيح $a$ أولي نسبياً مع $N$، إذا كان $a^{N-1} \not\equiv 1 \pmod N$، فمن المؤكد أن $N$ عدد مؤلف&amp;rdquo;. باستخدام هذه الخاصية، يتم اختيار أساس (base) عشوائي $a$ للعدد المراد اختباره $N$، وحساب $a^{N-1} \pmod N$ للتحقق مما إذا كان يساوي $1$. هذا هو اختبار فيرما.&lt;/p>
&lt;h2 id="الأسس-النمطية-السريعة-التربيع-المتكرر">الأسس النمطية السريعة (التربيع المتكرر)
&lt;/h2>&lt;p>لإجراء اختبار فيرما، يجب حساب الأس الضخم $a^{N-1} \pmod N$ بسرعة. لهذا، نستخدم &amp;ldquo;التربيع المتكرر (Modular Exponentiation / Binary Exponentiation)&amp;rdquo;. التعقيد الزمني هو $O(\log N)$، وهو سريع جداً.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// حساب a^b mod m باستخدام التربيع المتكرر
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="nf">mod_pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">%=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">__int128_t&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">res&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">__int128_t&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">b&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>※ هنا، لمنع حدوث فيضان الأعداد (Overflow)، نستخدم امتداد GCC/Clang المسمى &lt;code>__int128_t&lt;/code> (عدد صحيح بحجم 128 بت) للاحتفاظ بالضرب الوسيط.&lt;/p>
&lt;h2 id="الأعداد-شبه-الأولية-وأعداد-كارمايكل-carmichael-numbers">الأعداد شبه الأولية وأعداد كارمايكل (Carmichael Numbers)
&lt;/h2>&lt;p>على الرغم من أن اختبار فيرما قوي للغاية، إلا أن لديه نقطة ضعف قاتلة. وهي وجود أعداد $N$ مؤلفة، ولكنها تحقق $a^{N-1} \equiv 1 \pmod N$ لجميع قيم $a$ (الأولية نسبياً مع $N$).&lt;/p>
&lt;p>تسمى هذه الأعداد بـ &amp;ldquo;الأعداد شبه الأولية المطلقة&amp;rdquo; أو &amp;ldquo;أعداد كارمايكل&amp;rdquo;. أصغر عدد كارمايكل هو $561 = 3 \times 11 \times 17$.
نظراً لوجود أعداد كارمايكل، لا يمكن إجراء اختبار حتمي بـ &amp;ldquo;احتمال 100%&amp;rdquo; باستخدام اختبار فيرما وحده. بغض النظر عن قيم $a$ المختلفة التي نختبرها، فإن عدداً مثل $561$ سيتظاهر دائماً بأنه عدد أولي (يخدعنا).&lt;/p>
&lt;hr>
&lt;h1 id="3-طريقة-ميلر-رابين-لاختبار-الأولية-miller-rabin-primality-test">3. طريقة ميلر-رابين لاختبار الأولية (Miller-Rabin Primality Test)
&lt;/h1>&lt;p>لقد تغلب كل من غاري ميلر (Gary L. Miller) ومايكل رابين (Michael O. Rabin) ببراعة على نقطة ضعف اختبار فيرما (وجود أعداد كارمايكل) من خلال ابتكار &amp;ldquo;طريقة ميلر-رابين لاختبار الأولية&amp;rdquo;.
حالياً، كخوارزمية عملية وسريعة لاختبار الأولية، تُستخدم على نطاق واسع في المكتبات الداخلية لمختلف لغات البرمجة وتوليد المفاتيح في أنظمة التشفير.&lt;/p>
&lt;h2 id="المبادئ-الرياضية">المبادئ الرياضية
&lt;/h2>&lt;p>بالإضافة إلى مبرهنة فيرما الصغرى، تستخدم خوارزمية ميلر-رابين الخاصية القائلة بأنه &amp;ldquo;في حقل البواقي للعدد الأولي ($\mathbb{Z}/p\mathbb{Z}$)، تقتصر حلول $x^2 \equiv 1 \pmod p$ على $x \equiv 1$ أو $x \equiv -1$&amp;rdquo; (في حالة كان المعامل عدداً مؤلفاً، قد توجد جذور تربيعية غير بديهية أخرى).&lt;/p>
&lt;p>العدد الفردي $N$ المراد اختباره مطروحاً منه $1$، أي $N-1$، سيكون بالتأكيد عدداً زوجياً. لذلك، نقوم بقسمة $N-1$ على $2$ قدر الإمكان، ونعبر عنه بالشكل التالي:
&lt;/p>
$$ N-1 = d \cdot 2^s $$
&lt;p>
(حيث $d$ عدد فردي، و $s \ge 1$)&lt;/p>
&lt;p>بالنسبة لأي أساس $a$ ($1 &lt; a &lt; N-1$)، نتحقق مما إذا كان $a^{N-1} \equiv 1 \pmod N$ وفقاً لمبرهنة فيرما الصغرى، ولكننا نقوم بهذا الحساب تدريجياً.
على وجه التحديد، نقوم بتكرار التربيع بالترتيب التالي: $a^d, a^{d \cdot 2}, a^{d \cdot 4}, \ldots, a^{d \cdot 2^s}$.&lt;/p>
&lt;p>لكي تقرر طريقة ميلر-رابين أن $N$ &amp;ldquo;عدد أولي (أو عدد أولي باحتمال كبير)&amp;quot;، يجب أن يتحقق &lt;strong>أي&lt;/strong> من الشروط التالية:&lt;/p>
&lt;ol>
&lt;li>$a^d \equiv 1 \pmod N$&lt;/li>
&lt;li>يوجد $r$ ($0 \le r &lt; s$) بحيث يتحقق $a^{d \cdot 2^r} \equiv -1 \pmod N$.
※ في عملية المعامل (Modulo) بلغة C++، يصبح $-1 \pmod N$ مساوياً لـ $N-1$.&lt;/li>
&lt;/ol>
&lt;p>إذا كان $N$ عدداً أولياً، فإن هذا الشرط سيتحقق بالتأكيد لأي $a$. على العكس، إذا كان $N$ عدداً مؤلفاً، فقد تم إثبات رياضياً أن احتمال تحقق هذا الشرط (احتمال الانخداع) عند اختيار $a$ عشوائياً هو أقل من أو يساوي $\frac{1}{4}$.
إذا قمنا بإجراء $k$ اختبارات مستقلة، فإن احتمال الخطأ في التحديد يصبح أقل من أو يساوي $\left(\frac{1}{4}\right)^k$، ويمكن اعتباره عملياً صفراً. لا توجد أعداد &amp;ldquo;يمكنها الخداع تماماً&amp;rdquo; مثل أعداد كارمايكل.&lt;/p>
&lt;h2 id="سير-خوارزمية-ميلر-رابين-مخطط-mermaid">سير خوارزمية ميلر-رابين (مخطط Mermaid)
&lt;/h2>&lt;p>يوضح الشكل التالي التدفق المنطقي لاختبار واحد في طريقة ميلر-رابين (اختبار لأساس واحد $a$).&lt;/p>
&lt;div class="mermaid">graph TD
Start["بدء الاختبار (الإدخال: N, a)"] --> CalcDS["حساب d (فردي) و s التي تحقق N-1 = d * 2^s"]
CalcDS --> CalcX["حساب x = a^d mod N"]
CalcX --> CheckX1{"هل x == 1 أو x == N-1 ؟"}
CheckX1 -- "نعم" --> ReturnTrue["يحتمل أن يكون أولياً (Probably Prime)"]
CheckX1 -- "لا" --> LoopStart["بدء حلقة r من 1 إلى s-1"]
LoopStart --> LoopCondition{"هل r &lt; s ؟"}
LoopCondition -- "لا" --> ReturnFalse["مؤلف بالتأكيد (Composite)"]
LoopCondition -- "نعم" --> SquareX["حساب x = (x * x) mod N"]
SquareX --> CheckXMinus1{"هل x == N - 1 ؟"}
CheckXMinus1 -- "نعم" --> ReturnTrue
CheckXMinus1 -- "لا" --> CheckXOne{"هل x == 1 ؟"}
CheckXOne -- "نعم" --> ReturnFalse
CheckXOne -- "لا" --> LoopNext["زيادة r بمقدار 1 والانتقال للتالي"]
LoopNext --> LoopCondition&lt;/div>
&lt;hr>
&lt;h1 id="4-الاختبار-الحتمي-للأعداد-الصحيحة-بحجم-64-بت">4. الاختبار الحتمي للأعداد الصحيحة بحجم 64 بت
&lt;/h1>&lt;p>على الرغم من أن طريقة ميلر-رابين هي أساساً خوارزمية &amp;ldquo;احتمالية&amp;rdquo;، إلا أنه عندما يكون الحد الأقصى لـ $N$ ثابتاً، يمكننا إجراء اختبار أولية &amp;ldquo;مؤكد بنسبة 100%&amp;rdquo; من خلال تجربة مجموعة محددة من قيم $a$ (الأساس).
يسمى هذا &lt;strong>اختبار ميلر-رابين الحتمي (Deterministic Miller-Rabin Test)&lt;/strong>.&lt;/p>
&lt;p>من خلال بحث Jim Sinclair وآخرين، تبين أنه بالنسبة لجميع الأعداد الصحيحة $N &lt; 2^{64}$ (حوالي $1.8 \times 10^{19}$)، يكفي اختيار الأعداد الأولية السبعة التالية كأساس $a$ واختبارها للحصول على تقييم حتمي وكامل بما فيه الكفاية.&lt;/p>
&lt;p>&lt;strong>قائمة الأساس $a$ المراد اختبارها:&lt;/strong>
&lt;code>{2, 325, 9375, 28178, 450775, 9780504, 1795265022}&lt;/code>&lt;/p>
&lt;p>أو، كمجموعة أخرى معروفة، يمكن التحديد بشكل مثالي لـ $N &lt; 2^{64}$ باستخدام الأعداد الأولية الـ $12$ التالية:
&lt;code>{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}&lt;/code>&lt;/p>
&lt;p>هذه المرة، من أجل تعزيز بساطة الخوارزمية وموثوقيتها، سنعتمد طريقة تستخدم الأعداد الأولية الـ $12$ الأخيرة كقاعدة (أو القواعد السبعة المحسنة). في تنفيذ C++، نقوم بتحسين يقلل من عدد الاختبارات إلى الحد الأدنى عن طريق تقسيم النطاقات باستخدام التفرع الشرطي.&lt;/p>
&lt;hr>
&lt;h1 id="5-تنفيذ-متقدم-بلغة-c-highly-optimized-c-implementation">5. تنفيذ متقدم بلغة C++ (Highly Optimized C++ Implementation)
&lt;/h1>&lt;p>الآن، سنقوم بتجميع النظرية الرياضية وتصميم الخوارزمية التي تناولناها حتى الآن، وسنقدم الكود المصدري لتنفيذ دالة اختبار ميلر-رابين للأولية بأعلى مستوى في لغة C++ الحديثة.&lt;/p>
&lt;h2 id="نقاط-التنفيذ">نقاط التنفيذ
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>&lt;strong>تجنب فيضان الضرب للأعداد الصحيحة 64 بت:&lt;/strong>
في حالة $N \approx 10^{18}$، يمكن أن يصل الحد الأقصى لـ $x \times x$ في الضرب النمطي إلى $10^{36}$، مما يتجاوز بسهولة الحد الأقصى للأنواع الصحيحة ذات 64 بت (&lt;code>uint64_t&lt;/code> أو &lt;code>long long&lt;/code>) وهو $1.8 \times 10^{19}$.
لحل هذه المشكلة، نستخدم النوع الممتد لـ GCC و Clang وهو &lt;code>__int128_t&lt;/code> (أو &lt;code>unsigned __int128&lt;/code>)، ونحسب المعامل (Modulo) بعد الحساب بدقة 128 بت. هذا يسمح بالضرب النمطي السريع دون استخدام خوارزميات معقدة.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>اختيار الأساس الحتمي:&lt;/strong>
عندما تكون قيمة $N$ صغيرة، نقوم بالتحسين بحيث لا نحتاج إلا لاختبار عدد قليل من الأسس (bases).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="كود-c-المصدري-الكامل">كود C++ المصدري الكامل
&lt;/h2>&lt;p>فيما يلي نعرض الكود المصدري للنسخة النهائية الجاهزة للاستخدام العملي. يمكن نسخ هذا الكود واستخدامه كما هو في بيئات البرمجة التنافسية وغيرها.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&lt;/span>&lt;span class="lnt">94
&lt;/span>&lt;span class="lnt">95
&lt;/span>&lt;span class="lnt">96
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cstdint&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;initializer_list&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// (a * b) mod m السريع باستخدام أعداد صحيحة 128 بت
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">inline&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="nf">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)((&lt;/span>&lt;span class="kt">unsigned&lt;/span> &lt;span class="n">__int128&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// حساب (base^exp) mod m باستخدام التربيع المتكرر
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="nf">mod_pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">exp&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base&lt;/span> &lt;span class="o">%=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// الاختبار الحتمي للأعداد الصحيحة 64-بت باستخدام طريقة ميلر-رابين
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">bool&lt;/span> &lt;span class="nf">is_prime_miller_rabin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// التحقق المسبق من القيم الحدية والأعداد الأولية الصغيرة
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">5&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">5&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">7&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// تحليل إلى الشكل n-1 = d * 2^s
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">d&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">s&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="n">d&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">d&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">s&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// قائمة الأسس (bases) المستخدمة في الاختبار
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// تحسين يقلل من عدد الأسس المختبرة بناءً على حجم N
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">bases&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">4759123141ULL&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">61&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">1122004669633ULL&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">13&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">23&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1662803&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 7 أسس حتمية لجميع الأعداد N &amp;lt; 2^64
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">bases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">325&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">9375&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">28178&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">450775&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">9780504&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1795265022&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// تنفيذ الاختبار لكل أساس
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="nl">a&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">bases&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">%=&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">continue&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// إذا كان a من مضاعفات n فلا يمكن التحديد ولكنه ليس أولياً
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">continue&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// اجتياز الشرط الأول، الانتقال للأساس التالي
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="n">composite&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// حلقة التكرار s-1 مرة (x = x^2 mod n)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">composite&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// اجتياز الشرط الثاني، يحتمل أن يكون أولياً
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// إذا لم يستوفِ أي شرط، فهو بالتأكيد عدد مؤلف
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">composite&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// إذا اجتاز الشروط لجميع الأسس، فهو أولي بالتأكيد
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// أمثلة للاختبار
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">test_cases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">1000000007&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// عدد أولي مشهور
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">998244353&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// عدد أولي مشهور
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">1000000000000000003&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// عدد أولي بالقرب من 10^18
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">1000000000000000007&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// عدد مؤلف (10^18 + 7)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">561&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// عدد كارمايكل (مؤلف)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">18446744073709551557ULL&lt;/span> &lt;span class="c1">// أحد أكبر الأعداد الأولية بالقرب من 2^64
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="nl">n&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">test_cases&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; is &amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">is_prime_miller_rabin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34;Prime&amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;Composite&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h1 id="6-تقييم-أداء-وتعقيد-الخوارزمية">6. تقييم أداء وتعقيد الخوارزمية
&lt;/h1>&lt;p>سنقوم بدراسة أداء الخوارزمية التي تم تنفيذها.&lt;/p>
&lt;h2 id="التعقيد-الزمني-time-complexity">التعقيد الزمني (Time Complexity)
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>طريقة القسمة التجريبية:&lt;/strong> $O(\sqrt{N})$&lt;/li>
&lt;li>&lt;strong>اختبار فيرما:&lt;/strong> حساب الأس $O(\log N) \times k$ ($k$ هو عدد المحاولات)&lt;/li>
&lt;li>&lt;strong>طريقة ميلر-رابين:&lt;/strong> حساب الأس والتكرار $O(\log N) \times k$&lt;/li>
&lt;/ul>
&lt;p>في بيئة 64 بت ($N \le 2^{64}$)، تتحقق طريقة ميلر-رابين الحتمية المذكورة أعلاه من $7$ أسس كحد أقصى. لذلك، يمكن اعتبار $k \le 7$ كثابت، ويكون التعقيد الزمني الإجمالي هو $O(\log N)$ بدقة.
حتى في الحالة القصوى ($N \approx 10^{19}$)، لا يتجاوز عدد خطوات التنفيذ $7 \times 64 = 448$ خطوة من العمليات الأساسية، ويكون وقت التنفيذ بضعة ميكروثانية ($10^{-6}$ ثانية) أو أقل. مقارنة بـ $O(\sqrt{N})$ لطريقة القسمة التجريبية (عدد التكرارات $\approx 4 \times 10^9$ مرة)، يتم تحقيق &lt;strong>تسريع بملايين المرات&lt;/strong>.&lt;/p>
&lt;h2 id="المزيد-من-التحسين-ضرب-مونتغمري-montgomery-multiplication">المزيد من التحسين: ضرب مونتغمري (Montgomery Multiplication)
&lt;/h2>&lt;p>في تنفيذ هذا المقال، نستخدم النوع الممتد 128 بت &lt;code>__int128_t&lt;/code> لإجراء القسمة (عملية المعامل &lt;code>%&lt;/code>). حتى في وحدات المعالجة المركزية الحديثة، تُعتبر قسمة الأعداد الصحيحة (تعليمات DIV) أمرًا مكلفًا يتطلب عشرات الدورات مقارنة بالجمع والضرب.&lt;/p>
&lt;p>قد يستخدم صانعو المكتبات والمبرمجون التنافسيون الذين يسعون إلى التحسين الأقصى تقنية تُعرف باسم &lt;strong>ضرب مونتغمري (Montgomery Multiplication)&lt;/strong>. ضرب مونتغمري هو خوارزمية مذهلة تستبدل عملية المعامل (القسمة) المكلفة بـ &amp;ldquo;إزاحة البتات (Bit Shifts) والضرب فقط&amp;rdquo; عن طريق تعيين الأرقام إلى &amp;ldquo;مساحة مونتغمري&amp;rdquo; الخاصة.
بدمج هذا في الضرب النمطي لاختبار ميلر-رابين، يمكن زيادة سرعة التنفيذ بمرتين إلى ثلاث مرات. نظراً لأن هذا موضوع عميق جداً، أود أن أشرحه بالتفصيل في مقال آخر.&lt;/p>
&lt;hr>
&lt;h1 id="7-الخلاصة">7. الخلاصة
&lt;/h1>&lt;p>في هذا المقال، قمنا بشرح شامل من أساسيات اختبار الأولية إلى المواضيع المتقدمة.
دعونا نراجع النقاط الرئيسية.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>طريقة القسمة التجريبية&lt;/strong> موثوقة، ولكن نظرًا لتعقيدها الزمني $O(\sqrt{N})$، تفتقر إلى الفائدة العملية عندما يتجاوز $N$ $10^{12}$.&lt;/li>
&lt;li>&lt;strong>اختبار فيرما&lt;/strong> سريع جدًا بـ $O(\log N)$، لكن له نقطة ضعف قاتلة تتمثل في انخداعه بالأعداد شبه الأولية المطلقة مثل أعداد كارمايكل.&lt;/li>
&lt;li>&lt;strong>طريقة ميلر-رابين لاختبار الأولية&lt;/strong> هي الخوارزمية الأكثر عملية وقوة والتي تقضي على نقاط ضعف اختبار فيرما.&lt;/li>
&lt;li>في تنفيذ C++، يمكن التعامل بأمان مع فيضان ضرب الأعداد الصحيحة 64 بت من خلال الاستفادة من &lt;code>__int128_t&lt;/code>.&lt;/li>
&lt;li>ضمن نطاق الأعداد الصحيحة 64 بت ($N &lt; 2^{64}$)، من خلال اختيار $7$ أو $12$ عدداً أولياً محدداً كأساس، &lt;strong>يمكن اختبار الأولية بشكل حتمي (دقيق 100%)&lt;/strong> وليس باحتمال.&lt;/li>
&lt;/ol>
&lt;p>يعد اختبار الأولية السريع تقنية لا مفر منها في الحسابات التي تتعامل مع أعداد ضخمة. كود المصدر لطريقة ميلر-رابين بـ C++ المقدم في هذا المقال قوي ويمكن استخدامه عملياً كما هو. يرجى الاستفادة منه في مشاريعك الخاصة أو مسابقات الخوارزميات.&lt;/p>
&lt;div class="mermaid">graph LR
TrialDivision["طريقة القسمة التجريبية (O(√N))"] --> Fermat["اختبار فيرما (O(log N), توجد نقاط ضعف)"]
Fermat --> MillerRabin["طريقة ميلر-رابين (O(log N), يمكن جعلها حتمية)"]
MillerRabin --> Montgomery["+ ضرب مونتغمري (تسريع المضاعف الثابت)"]
style MillerRabin fill:#f9f,stroke:#333,stroke-width:2px&lt;/div>
&lt;p>عالم الخوارزميات حيث تتقاطع البرمجة والرياضيات هو عالم جميل وعميق جداً. نأمل أن يكون هذا المقال مفيداً لتعلمك المستقبلي.&lt;/p>
&lt;hr>
&lt;p>&lt;em>Reference:&lt;/em>&lt;/p>
&lt;ul>
&lt;li>&lt;em>Pomerance, C., Selfridge, J. L., &amp;amp; Wagstaff, S. S. (1980). The pseudoprimes to 25.10^9. Mathematics of Computation.&lt;/em>&lt;/li>
&lt;li>&lt;em>Sinclair, J. (2011). Deterministic Miller-Rabin primality testing.&lt;/em>&lt;/li>
&lt;/ul></description></item><item><title>【شرح رياضيات】شرح آلية عمل تشفير RSA بطريقة يفهمها حتى طلاب الثانوية</title><link>http://kenji.blog/ar/p/rsa-encryption-math-explained-for-beginners/</link><pubDate>Fri, 11 Sep 2026 13:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/rsa-encryption-math-explained-for-beginners/</guid><description>&lt;img src="http://kenji.blog/p/rsa-encryption-math-explained-for-beginners/img/eyecatch.jpg" alt="Featured image of post 【شرح رياضيات】شرح آلية عمل تشفير RSA بطريقة يفهمها حتى طلاب الثانوية" />&lt;p>إحدى التقنيات التي تدعم أمن مجتمع الإنترنت من جذوره هي &amp;ldquo;تشفير RSA&amp;rdquo;. العديد من الاتصالات التي نستخدمها يوميًا دون تفكير، مثل مدفوعات بطاقات الائتمان في التسوق عبر الإنترنت، والتواصل مع الأصدقاء على شبكات التواصل الاجتماعي، وإرسال واستقبال المعلومات السرية للشركات، محمية بواسطة تشفير RSA أو التقنيات التي خلفته.&lt;/p>
&lt;p>ولكن عندما تسمع كلمة &amp;ldquo;تشفير&amp;rdquo;، قد تتخيل آلات تشفير معقدة كتلك التي تظهر في أفلام الجواسيس، أو رياضيات متقدمة للغاية لا يفهمها سوى بعض العباقرة. صحيح أن نظرية التشفير الحديثة تعتمد على رياضيات متقدمة، إلا أن &lt;strong>الآلية الأساسية لتشفير RSA يمكن فهمها تمامًا إذا كان لديك معرفة برياضيات المرحلة الثانوية (خصائص الأعداد الصحيحة، الأعداد الأولية، التطابق وغيرها)&lt;/strong>.&lt;/p>
&lt;p>في هذا المقال، ومن منطلق المعرفة برياضيات المرحلة الثانوية، سنشرح خطوة بخطوة وبشكل شامل المبادئ الرياضية التي يعمل بها تشفير RSA، ولماذا يصعب فك تشفيره. سنشرح بعناية مع استخدام أمثلة ملموسة حتى يتمكن حتى من يجدون صعوبة قليلة في الرياضيات من الفهم.&lt;/p>
&lt;hr>
&lt;h2 id="1-التشفير-بالمفتاح-المتماثل-والتشفير-بالمفتاح-المعلن">1. التشفير بالمفتاح المتماثل والتشفير بالمفتاح المعلن
&lt;/h2>&lt;p>قبل الخوض في الآلية الرياضية لتشفير RSA، دعونا أولاً ننظم الفكرة الأساسية للتشفير. تنقسم طرق التشفير بشكل عام إلى نوعين: &amp;ldquo;التشفير بالمفتاح المتماثل (المشترك)&amp;rdquo; و&amp;quot;التشفير بالمفتاح المعلن (العام)&amp;quot;.&lt;/p>
&lt;h3 id="11-حدود-طريقة-التشفير-بالمفتاح-المتماثل">1.1 حدود طريقة التشفير بالمفتاح المتماثل
&lt;/h3>&lt;p>العديد من الشفرات المستخدمة منذ القدم تسمى &amp;ldquo;طريقة التشفير بالمفتاح المتماثل&amp;rdquo;. وهي طريقة &lt;strong>تستخدم نفس المفتاح في &amp;ldquo;التشفير (تحويل الرسالة إلى نص مشفر سري)&amp;rdquo; و&amp;quot;فك التشفير (إعادة النص المشفر إلى الرسالة الأصلية)&amp;quot;&lt;/strong>.&lt;/p>
&lt;p>على سبيل المثال، لنفترض أن أليس تريد إرسال رسالة سرية إلى بوب. تضع أليس الرسالة في صندوق وتغلقه باستخدام قفل (مفتاح متماثل). لكي يفتح بوب ذلك الصندوق، يحتاج إلى امتلاك نفس المفتاح الذي استخدمته أليس.&lt;/p>
&lt;p>هذه الطريقة بها مشكلة كبيرة، وهي &amp;ldquo;مشكلة توزيع المفاتيح&amp;rdquo;. عندما تتواصل أليس وبوب، اللذان تفصل بينهما مسافة كبيرة، لأول مرة، كيف يمكنهما مشاركة المفتاح دون أن يتم التنصت عليهما؟ إذا سُرق المفتاح من قبل طرف ثالث أثناء إرساله بالبريد، فإن جميع الاتصالات المشفرة اللاحقة ستكون مكشوفة تمامًا.&lt;/p>
&lt;h3 id="12-الاختراع-الثوري-طريقة-التشفير-بالمفتاح-المعلن">1.2 الاختراع الثوري &amp;ldquo;طريقة التشفير بالمفتاح المعلن&amp;rdquo;
&lt;/h3>&lt;p>تم ابتكار &amp;ldquo;طريقة التشفير بالمفتاح المعلن&amp;rdquo; لحل مشكلة توزيع المفاتيح هذه. وتشفير RSA هو نوع من هذا التشفير.&lt;/p>
&lt;p>في طريقة التشفير بالمفتاح المعلن، يتم استخدام &lt;strong>مفتاحين مختلفين: &amp;ldquo;مفتاح للتشفير (المفتاح المعلن/العام)&amp;rdquo; و&amp;quot;مفتاح لفك التشفير (المفتاح السري/الخاص)&amp;quot;&lt;/strong>.&lt;/p>
&lt;ol>
&lt;li>يقوم المتلقي بوب بإنشاء زوج من &amp;ldquo;المفتاح المعلن&amp;rdquo; و&amp;quot;المفتاح السري&amp;quot;.&lt;/li>
&lt;li>ينشر بوب &amp;ldquo;المفتاح المعلن&amp;rdquo; للعالم أجمع (لا يهم من يحصل عليه).&lt;/li>
&lt;li>تستخدم المرسلة أليس &amp;ldquo;المفتاح المعلن&amp;rdquo; الخاص ببوب لتشفير رسالتها وإرسالها.&lt;/li>
&lt;li>لا يمكن فك تشفير الرسالة المشفرة إلا بواسطة &amp;ldquo;المفتاح السري&amp;rdquo; الذي يمتلكه بوب فقط.&lt;/li>
&lt;/ol>
&lt;p>إذا شبهنا ذلك بالقفل، فإن بوب يصنع الكثير من &amp;ldquo;الأقفال المفتوحة (المفاتيح المعلنة)&amp;rdquo; وينثرها في جميع أنحاء العالم. تضع أليس رسالتها الموجهة لبوب في صندوق وتغلقه باستخدام أحد أقفال بوب التي وجدتها. بمجرد إغلاق القفل، لا يمكن فتحه إلا باستخدام &amp;ldquo;المفتاح الرئيسي (المفتاح السري)&amp;rdquo; الذي يمتلكه بوب. حتى لو سرق شخص ما الصندوق في الطريق، فلا يمكنه فتحه لأنه لا يمتلك المفتاح الرئيسي.&lt;/p>
&lt;div class="mermaid">graph TD
A["أليس (المرسلة)"] --> B["نص صريح (رسالة)"]
B --> C["عملية التشفير"]
D["مفتاح بوب المعلن (متاح للجميع)"] --> C
C --> E["إرسال عبر الإنترنت: نص مشفر"]
E --> F["عملية فك التشفير"]
G["مفتاح بوب السري (يمتلكه بوب فقط)"] --> F
F --> H["النص الصريح المسترجع (الرسالة)"]
H --> I["بوب (المتلقي)"]&lt;/div>
&lt;p>لتحقيق هذا النظام الثوري، نحتاج إلى نوع من &lt;strong>&amp;ldquo;الدوال أحادية الاتجاه (لغز رياضي في اتجاه واحد)&amp;rdquo;&lt;/strong>، حيث &amp;ldquo;يمكن التشفير بسهولة باستخدام المفتاح المعلن، ولكن من المستحيل مطلقًا فك التشفير بدون المفتاح السري&amp;rdquo;. القطعة التي تم التركيز عليها لحل هذا اللغز هي &amp;ldquo;الأعداد الأولية&amp;rdquo; التي نعرفها جيدًا.&lt;/p>
&lt;hr>
&lt;h2 id="2-الأساس-الرياضي-الذي-يدعم-تشفير-rsa-1-الأعداد-الأولية-والتحليل-إلى-العوامل-الأولية">2. الأساس الرياضي الذي يدعم تشفير RSA 1: الأعداد الأولية والتحليل إلى العوامل الأولية
&lt;/h2>&lt;p>يعتمد أمان تشفير RSA على حقيقة رياضية مفادها أن &lt;strong>&amp;ldquo;تحليل الأعداد الضخمة إلى عواملها الأولية أمر صعب للغاية&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="21-ما-هو-العدد-الأولي">2.1 ما هو العدد الأولي
&lt;/h3>&lt;p>العدد الأولي هو &amp;ldquo;عدد طبيعي أكبر من 1، لا يقبل القسمة إلا على 1 وعلى نفسه&amp;rdquo;.
مثال: $2, 3, 5, 7, 11, 13, 17, 19, 23...$&lt;/p>
&lt;p>الأعداد الأولية تشبه &amp;ldquo;الذرات&amp;rdquo; لجميع الأعداد الصحيحة. يمكن تحليل أي عدد طبيعي إلى شكل ضرب أعداد أولية. وهذا ما يسمى &lt;strong>التحليل إلى العوامل الأولية&lt;/strong>. على سبيل المثال، إمكانية التحليل إلى عوامل أولية بطريقة واحدة فقط (إذا تجاهلنا الترتيب) كما في $60 = 2^2 \times 3 \times 5$ تُعرف باسم &amp;ldquo;المبرهنة الأساسية في الحساب&amp;rdquo;.&lt;/p>
&lt;h3 id="22-صعوبة-التحليل-إلى-العوامل-الأولية-الدالة-أحادية-الاتجاه">2.2 صعوبة التحليل إلى العوامل الأولية (الدالة أحادية الاتجاه)
&lt;/h3>&lt;p>المهم هنا هو عدم التماثل حيث أن &lt;strong>&amp;ldquo;عملية الضرب سهلة، لكن التحليل إلى العوامل الأولية صعب&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>على سبيل المثال، حاول حساب حاصل ضرب العددين الأوليين التاليين ذهنيًا:
$11 \times 13 = ?$
هذا سهل، أليس كذلك؟ الجواب هو $143$.&lt;/p>
&lt;p>إذًا، ماذا عن العدد التالي؟
حلل العدد $323$ إلى عوامله الأولية.
ما رأيك؟ سيستغرق الأمر بعض الوقت. (الجواب هو $17 \times 19$).&lt;/p>
&lt;p>إذا كانت الأعداد صغيرة، فيمكن للإنسان حسابها بطريقة ما، ولكن عندما تصبح الأعداد كبيرة، يصبح الحساب صعبًا بشكل هائل حتى باستخدام أجهزة الكمبيوتر. في تشفير RSA السائد حاليًا، يتم استخدام عدد $N = p \times q$ ناتج عن ضرب عددين أوليين ضخمين بشكل لا يصدق $p$ و $q$ بحجم 2048 بت (حوالي 600 رقم بالنظام العشري).&lt;/p>
&lt;p>عند إعطاء عددين أوليين ضخمين $p$ و $q$، فإن حساب $N$ يستغرق جزءًا من الثانية بالنسبة للكمبيوتر (أقل من مللي ثانية). ولكن على العكس من ذلك، إذا تم إعطاء $N$ فقط لإيجاد $p$ و $q$ الأصليين، فسيستغرق الأمر وقتًا طويلاً لا يمكن لأسرع حاسوب عملاق حالي حله حتى لو استمر في العمل لترليونات السنين.&lt;/p>
&lt;p>هذا &lt;strong>&amp;ldquo;عدم التماثل في الحساب (طريق الذهاب سهل، وطريق العودة صعب)&amp;rdquo;&lt;/strong> هو الأساس الذي يخلق العلاقة بين المفتاح المعلن والمفتاح السري.&lt;/p>
&lt;hr>
&lt;h2 id="3-الأساس-الرياضي-الذي-يدعم-تشفير-rsa-2-التطابق-حساب-المقياس">3. الأساس الرياضي الذي يدعم تشفير RSA 2: التطابق (حساب المقياس)
&lt;/h2>&lt;p>لا تتم حسابات تشفير RSA بالجمع والضرب حيث تكبر الأعداد بشكل لا نهائي كما نستخدمها عادة، بل تتم في عالم &amp;ldquo;البواقي&amp;rdquo; بعد القسمة على عدد معين. وهذا ما يسمى &lt;strong>التطابق (حساب المقياس أو الحساب المعياري)&lt;/strong>.&lt;/p>
&lt;h3 id="31-رياضيات-الساعة">3.1 رياضيات الساعة
&lt;/h3>&lt;p>غالبًا ما يُشبه حساب المقياس بـ &amp;ldquo;رياضيات الساعة&amp;rdquo;. إذا كانت الساعة الآن 10، فكم ستكون الساعة بعد 5 ساعات؟ إنها $10 + 5 = 15$، ولكن في نظام الساعة المعتاد المكون من 12 ساعة، نجيب &amp;ldquo;الساعة 3&amp;rdquo;. هذا لأن باقي قسمة 15 على 12 هو 3.&lt;/p>
&lt;p>في عالم الرياضيات، يُكتب هذا على النحو التالي:
&lt;/p>
$$ 15 \equiv 3 \pmod{12} $$
&lt;p>
ويُقرأ: &amp;ldquo;15 و 3 متطابقان بمقياس 12 (باقي قسمتهما على 12 متساوٍ)&amp;rdquo;.&lt;/p>
&lt;h3 id="32-الخصائص-الأساسية-للتطابق">3.2 الخصائص الأساسية للتطابق
&lt;/h3>&lt;p>للتطابق خصائص مفيدة جدًا تشبه إلى حد كبير خصائص المعادلة ($=$). لنفترض أن المقياس (القاسم) هو $N$.
عندما يكون $a \equiv b \pmod N$ و $c \equiv d \pmod N$، يتحقق ما يلي:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>الجمع:&lt;/strong> $a + c \equiv b + d \pmod N$&lt;/li>
&lt;li>&lt;strong>الطرح:&lt;/strong> $a - c \equiv b - d \pmod N$&lt;/li>
&lt;li>&lt;strong>الضرب:&lt;/strong> $a \times c \equiv b \times d \pmod N$&lt;/li>
&lt;li>&lt;strong>الرفع لأس:&lt;/strong> $a^k \equiv b^k \pmod N$ (حيث $k$ عدد طبيعي)&lt;/li>
&lt;/ol>
&lt;p>الخاصية الأكثر أهمية هي &amp;ldquo;الرفع لأس&amp;rdquo;. هذا يعني أن &lt;strong>&amp;ldquo;أس الباقي يساوي باقي الأس&amp;rdquo;&lt;/strong>.
على سبيل المثال، لنفترض أننا نريد إيجاد باقي قسمة $7^{100}$ على $5$. سيكون من الصعب جدًا ضرب $7$ في نفسها 100 مرة ثم القسمة على $5$، ولكن باستخدام خصائص التطابق، نظرًا لأن $7 \equiv 2 \pmod 5$، فإن $7^{100} \equiv 2^{100} \pmod 5$، مما يبسط الحساب بشكل هائل. هذه الخاصية لا غنى عنها في عالم التشفير لأننا نتعامل مع أسس لأعداد كبيرة جدًا.&lt;/p>
&lt;hr>
&lt;h2 id="4-الأساس-الرياضي-الذي-يدعم-تشفير-rsa-3-مؤشر-أويلر-ومبرهنة-أويلر">4. الأساس الرياضي الذي يدعم تشفير RSA 3: مؤشر أويلر ومبرهنة أويلر
&lt;/h2>&lt;p>من هنا تبدأ الرياضيات السحرية التي تشكل جوهر تشفير RSA. ستظهر &amp;ldquo;مبرهنة أويلر&amp;rdquo;، وهي تعميم لـ &amp;ldquo;مبرهنة فيرما الصغرى&amp;rdquo;.&lt;/p>
&lt;h3 id="41-دالة-مؤشر-أويلر-دالة-توتنت-phin">4.1 دالة مؤشر أويلر (دالة توتنت) $\phi(N)$
&lt;/h3>&lt;p>دالة مؤشر أويلر (دالة $\phi$) هي دالة تعيد، بالنسبة لعدد طبيعي معين $N$، &lt;strong>&amp;ldquo;عدد الأعداد الطبيعية من 1 إلى $N$ التي تكون أولية نسبيًا مع $N$ (أي القاسم المشترك الأكبر بينهما هو 1)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>دعونا نلقي نظرة على بعض الأمثلة:&lt;/p>
&lt;ul>
&lt;li>$\phi(5)$: من بين الأعداد 1, 2, 3, 4, 5، الأعداد الأولية نسبيًا مع 5 هي 1, 2, 3, 4 (عددها 4). إذن $\phi(5) = 4$.&lt;/li>
&lt;li>$\phi(6)$: من بين الأعداد 1, 2, 3, 4, 5, 6، الأعداد الأولية نسبيًا مع 6 هي 1, 5 (عددها 2). إذن $\phi(6) = 2$.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>【خاصية مميزة في حالة العدد الأولي】&lt;/strong>
إذا كان $p$ عددًا أوليًا، فإن جميع الأعداد من 1 إلى $p-1$ تكون أولية نسبيًا مع $p$. وبالتالي:
&lt;/p>
$$ \phi(p) = p - 1 $$
&lt;p>&lt;strong>【خاصية مميزة في حالة حاصل ضرب عددين أوليين】&lt;/strong>
بالنسبة لعددين أوليين مختلفين $p$ و $q$، إذا كان $N = p \times q$، فيمكن حساب $\phi(N)$ بسهولة كالتالي:
&lt;/p>
$$ \phi(N) = \phi(p) \times \phi(q) = (p - 1)(q - 1) $$
&lt;p>
هذه الخاصية تعمل كـ &amp;ldquo;باب خلفي سري (Trapdoor)&amp;rdquo; لتشفير RSA. فالشخص الذي يعرف $p$ و $q$ (منشئ المفتاح) يمكنه حساب $\phi(N)$ في لحظة، لكن الطرف الثالث الذي يعرف $N$ فقط لا يمكنه حساب $\phi(N)$ ما لم يقم بتحليل $N$ إلى عوامله الأولية.&lt;/p>
&lt;h3 id="42-مبرهنة-أويلر">4.2 مبرهنة أويلر
&lt;/h3>&lt;p>أثبت ليونهارد أويلر هذه المبرهنة الجميلة باستخدام $\phi(N)$:&lt;/p>
&lt;p>&lt;strong>مبرهنة أويلر:&lt;/strong>
عندما يكون العددان الصحيحان $a$ و $N$ أوليين نسبيًا، يتحقق التطابق التالي:
&lt;/p>
$$ a^{\phi(N)} \equiv 1 \pmod N $$
&lt;p>هذه خاصية مذهلة تعني أن &amp;ldquo;حاصل ضرب أي عدد $a$ في نفسه $\phi(N)$ مرة ثم قسمته على $N$، سيعطي باقيًا يساوي $1$ دائمًا&amp;rdquo;. (إذا كان $N$ عددًا أوليًا $p$، فإنها تصبح $a^{p-1} \equiv 1 \pmod p$، وتُعرف باسم مبرهنة فيرما الصغرى).&lt;/p>
&lt;p>دعونا نعدل مبرهنة أويلر هذه. سنضرب كلا الطرفين في $a$ مرة أخرى:
&lt;/p>
$$ a^{\phi(N) + 1} \equiv a \pmod N $$
&lt;p>علاوة على ذلك، بالنسبة لأي عدد صحيح $k$، فإن $a^{k \cdot \phi(N)}$ سيكون أيضًا $1^k = 1$، وبالتالي تتحقق المعادلة التالية:
&lt;/p>
$$ a^{k \cdot \phi(N) + 1} \equiv a \pmod N $$
&lt;p>هذه المعادلة بالذات هي المبدأ الأساسي الذي يجعل سحر تشفير RSA &lt;strong>&amp;ldquo;العودة إلى الحالة الأصلية بعد التشفير وفك التشفير&amp;rdquo;&lt;/strong> ممكنًا.&lt;/p>
&lt;hr>
&lt;h2 id="5-خوارزمية-تشفير-rsa-خطوات-إنشاء-المفتاح-التشفير-وفك-التشفير">5. خوارزمية تشفير RSA: خطوات إنشاء المفتاح، التشفير، وفك التشفير
&lt;/h2>&lt;p>بعد أن اكتملت المعرفة الأساسية، دعونا أخيرًا نلقي نظرة على الخطوات المحددة لتشفير RSA. ينقسم تشفير RSA بشكل رئيسي إلى ثلاث مراحل: &amp;ldquo;1. إنشاء المفتاح&amp;rdquo;، &amp;ldquo;2. التشفير&amp;rdquo;، و&amp;quot;3. فك التشفير&amp;quot;.&lt;/p>
&lt;div class="mermaid">flowchart TD
A1["1. اختيار عددين أوليين p, q"] --> A2["حساب N = p × q"]
A1 --> A3["حساب φ(N) = (p-1)(q-1)"]
A3 --> A4["اختيار e بحيث يكون أوليًا نسبيًا مع φ(N)"]
A3 --> A5["حساب d بحيث يتحقق التطابق e × d ≡ 1 (mod φ(N))"]
A2 --> A6["المفتاح المعلن (N, e)"]
A4 --> A6
A5 --> A7["المفتاح السري d"]
B1["2. النص الصريح (رسالة) M"] --> B2["حساب C ≡ M^e (mod N)"]
A6 -.-> B2
B2 --> B3["إرسال النص المشفر C"]
B3 --> C1["3. النص المشفر المُستلَم C"]
C1 --> C2["حساب M ≡ C^d (mod N)"]
A7 -.-> C2
C2 --> C3["الحصول على النص الصريح الأصلي M"]&lt;/div>
&lt;h3 id="51-إنشاء-المفتاح-key-generation">5.1 إنشاء المفتاح (Key Generation)
&lt;/h3>&lt;p>يقوم المتلقي بوب بإنشاء &amp;ldquo;مفتاح معلن&amp;rdquo; و&amp;quot;مفتاح سري&amp;quot; خاص به.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>اختيار الأعداد الأولية:&lt;/strong> يختار عشوائيًا عددين أوليين كبيرين $p$ و $q$.&lt;/li>
&lt;li>&lt;strong>حساب المقياس $N$:&lt;/strong> يحسب $N = p \times q$. هذا الـ $N$ سيتم إعلانه للجميع.&lt;/li>
&lt;li>&lt;strong>حساب $\phi(N)$:&lt;/strong> يحسب دالة أويلر $\phi(N) = (p - 1)(q - 1)$. هذا هو رقم بوب السري.&lt;/li>
&lt;li>&lt;strong>اختيار المفتاح المعلن $e$:&lt;/strong> يختار عددًا صحيحًا $e$ بحيث $1 &lt; e &lt; \phi(N)$ ويكون أوليًا نسبيًا مع $\phi(N)$.&lt;/li>
&lt;li>&lt;strong>حساب المفتاح السري $d$:&lt;/strong> يجد عددًا صحيحًا $d$ يحقق الشرط التالي:
$$ e \times d \equiv 1 \pmod{\phi(N)} $$
وهذا يعني، &amp;ldquo;العدد $d$ الذي يجعل باقي قسمة $e \times d$ على $\phi(N)$ يساوي $1$&amp;rdquo;.&lt;/li>
&lt;/ol>
&lt;p>وبهذا تكتمل تجهيزات المفاتيح.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>المفتاح المعلن:&lt;/strong> الزوج $(N, e)$. يتم نشره للعالم أجمع.&lt;/li>
&lt;li>&lt;strong>المفتاح السري:&lt;/strong> $d$. لا يخبر به أحداً على الإطلاق.&lt;/li>
&lt;/ul>
&lt;h3 id="52-التشفير-encryption">5.2 التشفير (Encryption)
&lt;/h3>&lt;p>لنفترض أن أليس تريد إرسال رسالة سرية $M$ إلى بوب. ($M$ هي أحرف تم تحويلها إلى أرقام، بحيث يكون $0 \le M &lt; N$). تستخدم أليس المفتاح المعلن لبوب $(N, e)$ للحساب كما يلي:&lt;/p>
$$ C \equiv M^e \pmod N $$
&lt;p>تحسب &amp;ldquo;باقي قسمة رسالة $M$ مرفوعة للأس $e$ على $N$، وهو $C$&amp;rdquo;. هذا الـ $C$ هو النص المشفر.&lt;/p>
&lt;h3 id="53-فك-التشفير-decryption">5.3 فك التشفير (Decryption)
&lt;/h3>&lt;p>يتلقى بوب النص المشفر $C$. يستخدم بوب المفتاح السري $d$ للحساب كما يلي:&lt;/p>
$$ M \equiv C^d \pmod N $$
&lt;p>عندما يحسب &amp;ldquo;باقي قسمة النص المشفر $C$ مرفوع للأس $d$ على $N$&amp;quot;، فإنه بشكل مذهل يسترجع الرسالة الأصلية $M$!&lt;/p>
&lt;hr>
&lt;h2 id="6-لماذا-يعود-إلى-حالته-الأصلية-عند-فك-التشفير-إثبات-رياضي">6. لماذا يعود إلى حالته الأصلية عند فك التشفير؟ (إثبات رياضي)
&lt;/h2>&lt;p>قد تتساءل: &amp;ldquo;كيف يمكن مجرد رفع $C$ للأس $d$ أن يعيده إلى $M$ الأصلي؟&amp;rdquo;. هنا تأتي قوة &amp;ldquo;مبرهنة أويلر&amp;rdquo; التي ذكرناها سابقًا.&lt;/p>
&lt;p>دعونا نعوض معادلة التشفير $C = M^e$ في معادلة فك التشفير $C^d \pmod N$:
&lt;/p>
$$ C^d \equiv (M^e)^d \equiv M^{ed} \pmod N $$
&lt;p>هنا، تذكر الخطوة 5 من عملية إنشاء المفتاح. اختار بوب $d$ بحيث يكون $e \times d \equiv 1 \pmod{\phi(N)}$. هذا يعني أن &amp;ldquo;$ed$ هو من مضاعفات $\phi(N)$ مضافًا إليه $1$&amp;rdquo;. باستخدام عدد صحيح $k$، يمكن كتابتها على النحو التالي:
&lt;/p>
$$ ed = k \cdot \phi(N) + 1 $$
&lt;p>نعوض هذا في جزء الأس ونفككه باستخدام قوانين الأسس:
&lt;/p>
$$ M^{ed} = M^{k \cdot \phi(N) + 1} = M^{k \cdot \phi(N)} \times M^1 = (M^{\phi(N)})^k \times M $$
&lt;p>هنا، بافتراض أن الرسالة $M$ و $N$ أوليان نسبيًا، فإنه وفقًا لـ &lt;strong>مبرهنة أويلر&lt;/strong>، يكون $M^{\phi(N)} \equiv 1 \pmod N$.
&lt;/p>
$$ (M^{\phi(N)})^k \times M \equiv 1^k \times M \equiv M \pmod N $$
&lt;p>وبالتالي، تتحقق المعادلة التالية بنجاح تام:
&lt;/p>
$$ C^d \equiv M \pmod N $$
&lt;p>أليس لا تعرف $d$، والمتنصت أيضًا لا يعرف $d$، لذا فإن الوحيد الذي يمكنه استخراج $M$ من $C$ هو بوب الذي يمتلك $d$.&lt;/p>
&lt;hr>
&lt;h2 id="7-مثال-تطبيقي-دعونا-نجرب-تشفير-rsa-بالحساب-اليدوي-باستخدام-أعداد-أولية-صغيرة">7. مثال تطبيقي: دعونا نجرب تشفير RSA بالحساب اليدوي باستخدام أعداد أولية صغيرة
&lt;/h2>&lt;p>دعونا نقوم بتجربة تواصل مشفر من أليس إلى بوب باستخدام أرقام صغيرة (أعداد أولية) في الواقع.&lt;/p>
&lt;p>&lt;strong>【مرحلة إنشاء المفتاح لبوب】&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>يختار عددين أوليين $p=11$, $q=13$.&lt;/li>
&lt;li>يحسب $N = 11 \times 13 = 143$.&lt;/li>
&lt;li>يحسب $\phi(N) = (11 - 1) \times (13 - 1) = 10 \times 12 = 120$.&lt;/li>
&lt;li>يختار مفتاحًا معلنًا $e$ يكون أوليًا نسبيًا مع $\phi(N)=120$. لنختر هنا $e=7$.&lt;/li>
&lt;li>يجد المفتاح السري $d$. يبحث عن $d$ الذي يحقق $7 \times d \equiv 1 \pmod{120}$.
في المعادلة $7d = 120k + 1$، عندما يكون $k=6$ يصبح الناتج $721$، و $721 \div 7 = 103$.
وبالتالي، $d = 103$.&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>المفتاح المعلن: $(N=143, e=7)$&lt;/li>
&lt;li>المفتاح السري: $d=103$&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>【مرحلة التشفير لأليس】&lt;/strong>
لنفترض أنها تريد إرسال الرسالة $M = 9$.
المعادلة: $C \equiv 9^7 \pmod{143}$
$9^7 = 4,782,969$. بقسمة هذا العدد على 143 نحصل على $33447$ والباقي $48$.
أصبح النص المشفر $C = 48$.&lt;/p>
&lt;p>&lt;strong>【مرحلة فك التشفير لبوب】&lt;/strong>
يتلقى بوب النص المشفر $C = 48$، ويستخدم المفتاح السري $d = 103$ لفك التشفير.
المعادلة: $M \equiv 48^{103} \pmod{143}$
عند تنفيذ &lt;code>(48 ** 103) % 143&lt;/code> على الآلة الحاسبة، ستجد أن النتيجة بشكل رائع هي &amp;ldquo;&lt;strong>9&lt;/strong>&amp;rdquo;! لقد تمكن من استلام الرسالة الأصلية بنجاح.&lt;/p>
&lt;hr>
&lt;h2 id="8-كيفية-إيجاد-المفتاح-السري-d-خوارزمية-إقليدس-الممتدة">8. كيفية إيجاد المفتاح السري $d$: خوارزمية إقليدس الممتدة
&lt;/h2>&lt;p>في مثال الحساب اليدوي، اعتمدنا على التخمين للبحث عن $k$ وإيجاد $d=103$، لكن هذه الطريقة مستحيلة عندما تتكون الأعداد من مئات الأرقام. في البرامج الحقيقية، تُستخدم خوارزمية تسمى &lt;strong>&amp;ldquo;خوارزمية إقليدس الممتدة&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>حل التطابق $7d \equiv 1 \pmod{120}$ هو نفسه إيجاد الأعداد الصحيحة $d, y$ التي تحقق المعادلة $7d + 120y = 1$. من خلال الحساب العكسي لخوارزمية إقليدس، يمكن إيجاد ذلك ميكانيكيًا.&lt;/p>
&lt;ol>
&lt;li>$120 \div 7 = 17$ والباقي $1$&lt;/li>
&lt;li>بتعديل هذه المعادلة نحصل على: $1 = 120 - 17 \times 7$&lt;/li>
&lt;li>بمعنى آخر، $-17 \times 7 \equiv 1 \pmod{120}$&lt;/li>
&lt;/ol>
&lt;p>الرقم $-17$ يحمل نفس المعنى مثل $120 - 17 = 103$ في عالم المقياس $120$. وبالتالي، يمكن إيجاد $d = 103$ في لحظة. تتيح هذه الطريقة إجراء حسابات سريعة جدًا بغض النظر عن مدى ضخامة الأعداد.&lt;/p>
&lt;hr>
&lt;h2 id="9-الوجه-الآخر-لتشفير-rsa-التوقيع-الرقمي">9. الوجه الآخر لتشفير RSA: التوقيع الرقمي
&lt;/h2>&lt;p>من الميزات الرائعة لتشفير RSA أنه يمكن استخدامه أيضًا كـ &lt;strong>&amp;ldquo;توقيع رقمي&amp;rdquo;&lt;/strong> عن طريق عكس أدوار المفتاح المعلن والمفتاح السري.&lt;/p>
&lt;p>في التشفير كان الإجراء &amp;ldquo;التشفير بالمفتاح المعلن $\Rightarrow$ فك التشفير بالمفتاح السري&amp;rdquo;،
أما في التوقيع الرقمي، نتبع خطوات &amp;ldquo;التشفير بالمفتاح السري $\Rightarrow$ فك التشفير بالمفتاح المعلن&amp;rdquo;.&lt;/p>
&lt;div class="mermaid">flowchart TD
A1["1. أليس تنشئ توقيعًا باستخدام مفتاحها السري"] --> A2["S ≡ M^d (mod N)"]
A2 --> A3["إرسال الرسالة M والتوقيع S"]
A3 --> B1["2. بوب يتحقق من التوقيع باستخدام المفتاح المعلن"]
B1 --> B2["حساب M' ≡ S^e (mod N)"]
B2 --> B3["التحقق مما إذا كان M' يتطابق مع M"]&lt;/div>
&lt;p>تستخدم أليس مفتاحها السري $d$ لتحويل الرسالة (وهذا هو التوقيع $S$)، وترسله إلى بوب. يستخدم بوب المفتاح المعلن لأليس $e$ لإجراء عملية التحقق. إذا كانت نتيجة الحساب تتطابق مع الرسالة الأصلية، فإن ذلك يثبت في نفس الوقت أن &amp;ldquo;هذه البيانات لا يمكن إنشاؤها إلا بواسطة المفتاح السري لأليس&amp;rdquo;، و&amp;quot;لم يتم التلاعب بالرسالة في الطريق&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="10-تجربة-تشفير-rsa-من-خلال-البرمجة">10. تجربة تشفير RSA من خلال البرمجة
&lt;/h2>&lt;p>حسابات الأسس التي تعتبر صعبة في الحساب اليدوي، يمكن تنفيذها بسهولة بالغة باستخدام بايثون (Python). وفيما يلي كود بايثون يمكنك من خلاله تجربة المنطق الأساسي لتشفير RSA.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;إيجاد القاسم المشترك الأكبر&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">mod_inverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;إيجاد المفتاح السري d (باستخدام الدالة المدمجة في بايثون 3.8 وما بعده)&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. إنشاء المفتاح&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">11&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">13&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">N&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">q&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">phi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">e&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">7&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">d&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_inverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;المفتاح المعلن: (N=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, e=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">), المفتاح السري: d=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">d&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. التشفير&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ciphertext&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;النص المشفر: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">ciphertext&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. فك التشفير&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">decrypted_message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ciphertext&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;الرسالة بعد فك التشفير: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">decrypted_message&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>تستخدم دالة &lt;code>pow(base, exp, mod)&lt;/code> في بايثون خوارزمية سريعة تسمى &amp;ldquo;التربيع المتكرر (Exponentiation by squaring)&amp;rdquo; داخليًا، لذلك حتى بالنسبة للأعداد المكونة من مئات الأرقام، ينتهي الحساب في لحظة.&lt;/p>
&lt;hr>
&lt;h2 id="11-الخلاصة-وتقنيات-التشفير-المستقبلية">11. الخلاصة وتقنيات التشفير المستقبلية
&lt;/h2>&lt;p>لقد قمنا بتوضيح آلية عمل تشفير RSA بناءً على المعرفة برياضيات المرحلة الثانوية.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>صعوبة التحليل إلى العوامل الأولية:&lt;/strong> حساب $p \times q = N$ سهل، لكن إيجاد $p, q$ من $N$ صعب للغاية.&lt;/li>
&lt;li>&lt;strong>التطابق ومبرهنة أويلر:&lt;/strong> بفضل القاعدة $a^{\phi(N)} \equiv 1 \pmod N$، يكتمل &amp;ldquo;الباب الخلفي&amp;rdquo; السحري الذي يسمح بـ &amp;ldquo;العودة إلى الحالة الأصلية عند الرفع لأس عدد معين&amp;rdquo;.&lt;/li>
&lt;li>&lt;strong>المفتاح المعلن والمفتاح السري:&lt;/strong> يمكن لأي شخص التشفير، ولكن المستلم الشرعي فقط هو من يمكنه فك التشفير.&lt;/li>
&lt;/ol>
&lt;p>الـ $N$ المستخدم في تشفير RSA الحالي يتكون من أكثر من 600 رقم، وحتى لو تم حشد جميع الحواسيب العملاقة في العالم، فإن التحليل إلى العوامل الأولية سيستغرق وقتًا أطول من عمر الكون. ومع ذلك، عندما تصبح &amp;ldquo;الحواسيب الكمومية&amp;rdquo;، التي تتقدم الأبحاث بشأنها في السنوات الأخيرة، قابلة للتطبيق العملي في المستقبل، فهناك احتمال أن يتم حل هذا التحليل إلى العوامل الأولية في لحظة بواسطة &amp;ldquo;خوارزمية شور&amp;rdquo;. لذلك، يجري حاليًا تطوير &amp;ldquo;تشفير مقاوم للحواسيب الكمومية&amp;rdquo;، والذي لا يمكن حتى للحواسيب الكمومية فك تشفيره، بوتيرة سريعة في جميع أنحاء العالم.&lt;/p>
&lt;p>الرياضيات المتقدمة التي غالبًا ما يُعتقد أنها &amp;ldquo;غير مفيدة&amp;rdquo;، تحمي في الواقع حياتنا اليومية من جذورها. يعتبر تشفير RSA من أفضل المواد التعليمية التي توضح لنا عمق وجمال هذه الرياضيات. نأمل أن تكون قد شعرت ولو قليلاً بمتعة التشفير والرياضيات من خلال هذا المقال.&lt;/p></description></item></channel></rss>