Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: trekhleb/javascript-algorithms
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: yomalbalooshi/javascript-algorithms
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 6 commits
  • 4 files changed
  • 1 contributor

Commits on Aug 19, 2024

  1. Copy the full SHA
    3f6d4a2 View commit details
  2. Copy the full SHA
    e51a84c View commit details
  3. Copy the full SHA
    371f9b5 View commit details
  4. Copy the full SHA
    d5ca26e View commit details
  5. Add ar-AR translation for cryptography/polynomial-hash

    Polynomial hash translation
    yomalbalooshi authored Aug 19, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    0c37b49 View commit details
  6. Add ar-AR translation for cryptography/rail-fence-cipher

    Rail fence cipher translation
    yomalbalooshi authored Aug 19, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    17f4eb0 View commit details
30 changes: 30 additions & 0 deletions src/algorithms/cryptography/caesar-cipher/README.ar-AR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# التشفير بخوارزمية القيصر

في علم التشفير، تعد **شفرة قيصر**، المعروفة أيضًا باسم **شفرة سيزار**، أو **شفرة الإزاحة**، أو **كود قيصر** أو **إزاحة قيصر**، واحدة من أبسط وأشهر تقنيات التشفير. وهي نوع من شفرات الاستبدال حيث يتم استبدال كل حرف في النص الأصلي بحرف آخر يقع على بعد عدد ثابت من المواضع في الأبجدية. على سبيل المثال، مع إزاحة يسارية بمقدار `3`، سيتم استبدال حرف `D` بحرف `A`، وسيصبح `E` حرف `B`، وهكذا. سُميت هذه الطريقة على اسم يوليوس قيصر، الذي استخدمها في مراسلاته الخاصة.

![شفرة سيزار](https://upload.wikimedia.org/wikipedia/commons/4/4a/Caesar_cipher_left_shift_of_3.svg)

## مثال

يمكن تمثيل التحويل عن طريق محاذاة أبجديتين؛ حيث تكون الأبجدية المشفرة هي الأبجدية العادية التي تم تدويرها إلى اليسار أو اليمين بعدد معين من المواضع. على سبيل المثال، هذه شفرة قيصر تستخدم دوران يساري بمقدار ثلاثة مواضع، وهو ما يعادل إزاحة يمينية بمقدار 23 (يتم استخدام معامل الإزاحة كمفتاح):

```text
العادي: ABCDEFGHIJKLMNOPQRSTUVWXYZ
المشفر: XYZABCDEFGHIJKLMNOPQRSTUVW
```

عند التشفير، يبحث الشخص عن كل حرف من الرسالة في السطر "العادي" ويكتب الحرف المقابل له في السطر "المشفر"

```text
العادي: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
المشفر: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD
```

## التعقيد

- الوقت: `O(|n|)`
- المساحة: `O(|n|)`

## مراجع

- [شفرة قيصر على ويكيبيديا](https://en.wikipedia.org/wiki/Caesar_cipher)
94 changes: 94 additions & 0 deletions src/algorithms/cryptography/hill-cipher/README.ar-AR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# شفرة هيل

تعد **شفرة هيل** نوعًا من [شفرات الاستبدال متعددة الأحرف](https://en.wikipedia.org/wiki/Polygraphic_substitution) المبنية على الجبر الخطي.

يتم تمثيل كل حرف برقم [بالنسبة لـ](https://en.wikipedia.org/wiki/Modular_arithmetic) `26`. على الرغم من أن هذه ليست ميزة أساسية للشفرة، إلا أن هذا المخطط البسيط غالبًا ما يُستخدم:

| **Letter** | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| ---------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| **Number** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |

## التشفير

لتشفير رسالة، يتم ضرب كل مجموعة من `n` أحرف (تعتبر كمتجه ذو `n` مكون) في مصفوفة قابلة للعكس بأبعاد `n × n`، وذلك بالنسبة لـ `26`.

المصفوفة المستخدمة للتشفير هي _مفتاح الشفرة_، ويجب اختيارها عشوائيًا من مجموعة المصفوفات القابلة للعكس بأبعاد `n × n` (بالنسبة لـ `26`). يمكن بالطبع تكييف الشفرة لأبجدية بأي عدد من الأحرف؛ فقط يجب إجراء جميع العمليات الحسابية بالنسبة لعدد الأحرف بدلاً من النسبة لـ `26`.

لنأخذ الرسالة `ACT`، والمفتاح أدناه (أو `GYB/NQK/URP` بالأحرف):

```
| 6 24 1 |
| 13 16 10 |
| 20 17 15 |
```

بما أن `A` هو `0`، و `C` هو `2` و `T` هو `19`، فإن الرسالة هي المتجه:

```
| 0 |
| 2 |
| 19 |
```

وبالتالي، فإن المتجه المشفر يُعطى بـ:

```
| 6 24 1 | | 0 | | 67 | | 15 |
| 13 16 10 | | 2 | = | 222 | ≡ | 14 | (mod 26)
| 20 17 15 | | 19 | | 319 | | 7 |
```

الآن، لنفترض أن رسالتنا هي `CAT` بدلاً من ذلك (لاحظ كيف نستخدم نفس الأحرف كما في `ACT` هنا)، أو:

```
| 2 |
| 0 |
| 19 |
```

هذه المرة، المتجه المشفر يُعطى بـ:

```
| 6 24 1 | | 2 | | 31 | | 5 |
| 13 16 10 | | 0 | = | 216 | ≡ | 8 | (mod 26)
| 20 17 15 | | 19 | | 325 | | 13 |
```

وهو ما يقابل النص المشفر `FIN`. لقد تغير كل حرف.

## فك التشفير

لفك تشفير الرسالة، يتم ضرب كل مجموعة في معكوس المصفوفة المستخدمة للتشفير. نحول النص المشفر مرة أخرى إلى متجه، ثم نضرب ببساطة في معكوس مصفوفة المفتاح (`IFK/VIV/VMI` بالأحرف). (انظر [عكس المصفوفة](https://en.wikipedia.org/wiki/Matrix_inversion) للحصول على طرق حساب المصفوفة العكسية.) نجد أنه، بالنسبة لـ 26، معكوس المصفوفة المستخدمة في المثال السابق هو:

```
-1
| 6 24 1 | | 8 5 10 |
| 13 16 10 | (mod 26) ≡ | 21 8 21 |
| 20 17 15 | | 21 12 8 |
```

باستخدام النص المشفر السابق `POH`، نحصل على:

```
| 8 5 10 | | 15 | | 260 | | 0 |
| 21 8 21 | | 14 | = | 574 | ≡ | 2 | (mod 26)
| 21 12 8 | | 7 | | 539 | | 19 |
```

وهو ما يعيدنا إلى `ACT`، كما هو متوقع.

## تحديد مصفوفة التشفير

هناك تعقيدان في اختيار مصفوفة التشفير:

١. ليس لجميع المصفوفات معكوس. سيكون للمصفوفة معكوس إذا وفقط إذا كان [محددها](https://en.wikipedia.org/wiki/Determinant) غير صفري.

٢. يجب ألا يكون لمحدد مصفوفة التشفير أي عوامل مشتركة مع الأساس المعياري.

وبالتالي، إذا عملنا بالنسبة لـ `26` كما هو موضح أعلاه، يجب أن يكون المحدد غير صفري، ويجب ألا يكون قابلاً للقسمة على `2` أو `13`. إذا كان المحدد `0`، أو كان له عوامل مشتركة مع الأساس المعياري، فلا يمكن استخدام المصفوفة في شفرة هيل، ويجب اختيار مصفوفة أخرى (وإلا فلن يكون من الممكن فك التشفير). لحسن الحظ، المصفوفات التي تستوفي الشروط لاستخدامها في شفرة هيل شائعة نسبيًا.

## المراجع

- [شفرة هيل على ويكيبيديا](https://en.wikipedia.org/wiki/Hill_cipher)
- [عكس المصفوفة على MathIsFun](https://www.mathsisfun.com/algebra/matrix-inverse.html)
- [GeeksForGeeks](https://www.geeksforgeeks.org/hill-cipher/)
88 changes: 88 additions & 0 deletions src/algorithms/cryptography/polynomial-hash/README.ar-AR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# التجزئة الدوارة متعددة الحدود

## دالة التجزئة

تُستخدم **دوال التجزئة** لتعيين مجموعات بيانات كبيرة من العناصر ذات طول عشوائي (_المفاتيح_) إلى مجموعات بيانات أصغر من العناصر ذات طول ثابت (_البصمات_).

التطبيق الأساسي للتجزئة هو الاختبار الفعال لتساوي المفاتيح من خلال مقارنة بصماتها.

يحدث _التصادم_ عندما يكون لمفتاحين مختلفين نفس البصمة. الطريقة التي يتم بها التعامل مع التصادمات حاسمة في معظم تطبيقات التجزئة. التجزئة مفيدة بشكل خاص في بناء خوارزميات عملية فعالة.

## التجزئة الدوارة

**التجزئة الدوارة** (تُعرف أيضًا باسم التجزئة التكرارية أو المجموع الاختباري الدوار) هي دالة تجزئة حيث يتم تجزئة المدخلات في نافذة تتحرك عبر المدخلات.

تسمح بعض دوال التجزئة بحساب التجزئة الدوارة بسرعة كبيرة - يتم حساب قيمة التجزئة الجديدة بسرعة بناءً على البيانات التالية فقط:

- قيمة التجزئة القديمة،
- القيمة القديمة المزالة من النافذة،
- والقيمة الجديدة المضافة إلى النافذة.

## تجزئة السلاسل متعددة الحدود

يجب أن تعتمد دالة التجزئة المثالية للسلاسل بشكل واضح على كل من _مجموعة_ الرموز الموجودة في المفتاح وعلى _ترتيب_ الرموز. العائلة الأكثر شيوعًا لمثل هذه الدوال التجزئة تعامل رموز السلسلة كمعاملات _متعددة حدود_ مع متغير صحيح `p` وتحسب قيمته بالنسبة لثابت صحيح `M`:

غالبًا ما يتم شرح _خوارزمية البحث عن السلاسل Rabin-Karp_ باستخدام دالة تجزئة دوارة بسيطة جدًا تستخدم فقط عمليات الضرب والإضافة - **التجزئة الدوارة متعددة الحدود**:

> H(s<sub>0</sub>, s<sub>1</sub>, ..., s<sub>k</sub>) = s<sub>0</sub> _ p<sup>k-1</sup> + s<sub>1</sub> _ p<sup>k-2</sup> + ... + s<sub>k</sub> \* p<sup>0</sup>
حيث `p` هو ثابت، و _(s<sub>1</sub>، ... ، s<sub>k</sub>)_ هي أحرف الإدخال.

على سبيل المثال، يمكننا تحويل السلاسل القصيرة إلى أرقام مفاتيح عن طريق ضرب رموز الأرقام في قوى ثابتة. يمكن تحويل الكلمة المكونة من ثلاثة أحرف `ace` إلى رقم عن طريق حساب:

> key = 1 _ 26<sup>2</sup> + 3 _ 26<sup>1</sup> + 5 \* 26<sup>0</sup>
لتجنب التعامل مع قيم `H` ضخمة، يتم إجراء جميع العمليات الحسابية بالنسبة لـ `M`.

> H(s<sub>0</sub>, s<sub>1</sub>, ..., s<sub>k</sub>) = (s<sub>0</sub> _ p<sup>k-1</sup> + s<sub>1</sub> _ p<sup>k-2</sup> + ... + s<sub>k</sub> \* p<sup>0</sup>) mod M
الاختيار الدقيق للمعلمات `M`، `p` مهم للحصول على خصائص "جيدة" لدالة التجزئة، أي معدل تصادم منخفض.

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

```javascript
function hash(key, arraySize) {
const base = 13

let hash = 0
for (let charIndex = 0; charIndex < key.length; charIndex += 1) {
const charCode = key.charCodeAt(charIndex)
hash += charCode * base ** (key.length - charIndex - 1)
}

return hash % arraySize
}
```

طريقة `hash()` ليست فعالة كما يمكن أن تكون. بخلاف تحويل الأحرف، هناك عمليتا ضرب وإضافة داخل الحلقة. يمكننا إزالة عملية ضرب واحدة باستخدام **طريقة هورنر**:

> a<sub>4</sub> _ x<sup>4</sup> + a<sub>3</sub> _ x<sup>3</sup> + a<sub>2</sub> _ x<sup>2</sup> + a<sub>1</sub> _ x<sup>1</sup> + a<sub>0</sub> = (((a<sub>4</sub> _ x + a<sub>3</sub>) _ x + a<sub>2</sub>) _ x + a<sub>1</sub>) _ x + a<sub>0</sub>
بعبارة أخرى:

> H<sub>i</sub> = (P \* H<sub>i-1</sub> + S<sub>i</sub>) mod M
لا يمكن لـ `hash()` التعامل مع السلاسل الطويلة لأن hashVal تتجاوز حجم int. لاحظ أن المفتاح ينتهي دائمًا بأن يكون أقل من حجم المصفوفة. في طريقة هورنر يمكننا تطبيق عامل التشغيل modulo (٪) في كل خطوة من الحساب. هذا يعطي نفس النتيجة كتطبيق عامل التشغيل modulo مرة واحدة في النهاية، ولكنه يتجنب التجاوز.

```javascript
function hash(key, arraySize) {
const base = 13

let hash = 0
for (let charIndex = 0; charIndex < key.length; charIndex += 1) {
const charCode = key.charCodeAt(charIndex)
hash = (hash * base + charCode) % arraySize
}

return hash
}
```

التجزئة متعددة الحدود لها خاصية دوارة: يمكن تحديث البصمات بكفاءة عند إضافة الرموز أو إزالتها من نهايات السلسلة (بشرط تخزين مصفوفة من قوى p بالنسبة لـ M بطول كافٍ). تعتمد خوارزمية مطابقة النمط Rabin-Karp الشائعة على هذه الخاصية

## المراجع

- [أين تُستخدم دالة التجزئة للسلاسل النصية متعددة الحدود](https://www.mii.lt/olympiads_in_informatics/pdf/INFOL119.pdf)
- [التجزئة على موقع جامعة تكساس](https://www.cs.utexas.edu/~mitra/csSpring2017/cs313/lectures/hash.html)
- [دالة التجزئة على ويكيبيديا](https://en.wikipedia.org/wiki/Hash_function)
- [التجزئة المتدحرجة على ويكيبيديا](https://en.wikipedia.org/wiki/Rolling_hash)
28 changes: 28 additions & 0 deletions src/algorithms/cryptography/rail-fence-cipher/README.ar-AR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# شفرة السياج المتعرج

**شفرة السياج المتعرج** (تسمى أيضًا **شفرة المتعرج**) هي [شفرة تبديل](https://ar.wikipedia.org/wiki/تشفير_بالتبديل) يتم فيها تقسيم الرسالة على مجموعة من القضبان على سياج للترميز. يتم ملء السياج بأحرف الرسالة، بدءًا من أعلى اليسار وإضافة حرف في كل موضع، مع عبورها قطريًا إلى الأسفل. عند الوصول إلى القضيب الأخير، يجب أن يتحول الاتجاه قطريًا وصعودًا إلى القضيب الأول في حركة متعرجة. كرر هذه العملية حتى يتم توزيع الرسالة بالكامل على السياج. الرسالة المشفرة هي نتيجة دمج النص في كل قضيب، من الأعلى إلى الأسفل.

من [ويكيبيديا](https://ar.wikipedia.org/wiki/شفرة_السياج_المتعرج)، هذا هو شكل الرسالة `WE ARE DISCOVERED. FLEE AT ONCE` على سياج ذو `3` قضبان:

```
W . . . E . . . C . . . R . . . L . . . T . . . E
. E . R . D . S . O . E . E . F . E . A . O . C .
. . A . . . I . . . V . . . D . . . E . . . N . .
-------------------------------------------------
WECRLTEERDSOEEFEAOCAIVDEN
```

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

```
W . . . E . . . C . . . R . . . L . . . T . . . E
. - . - . - . - . - . - . - . - . - . - . - . - .
. . - . . . - . . . - . . . - . . . - . . . - . .
```

حان الوقت لبدء ملء القضيب التالي بمجرد أن يصبح عدد مواقع السياج التي تمت زيارتها مساويًا لعدد الأحرف في الرسالة.

## المراجع

- [شفرة السياج المتعرج على ويكيبيديا](https://ar.wikipedia.org/wiki/شفرة_السياج_المتعرج)
- [حاسبة شفرة السياج المتعرج](https://crypto.interactive-maths.com/rail-fence-cipher.html)