اكتب مُهايئًا للتدفّق يحتوي على مرجع إلى مفتاح، ويطبّق عليه عملية XOR على مستوى البتات مع بيانات اعتباطية.
عملية XOR هي عملية ثنائية أساسية: فلكل بت في المدخلات، اضبط البت المقابل في المخرجات على 1 إذا اختلف بتا المدخلين. وإذا كان كلا المدخلين 1 أو كانا معًا 0، فإن بت المخرجات المقابل يكون 0.
عند تطبيق XOR على مستند باستخدام مفتاح، يُكرَّر المفتاح بقدر ما يلزم من المرات، فينتج مستند مخرجات يساوي في الطول مستند الإدخال.
استُخدم تطبيق XOR على مستند باستخدام مفتاح في التشفير حتى أوائل القرن العشرين. ورغم أن هذه الطريقة صارت قديمة تمامًا لإخفاء البيانات، فقد تكون مفيدة على نحو مفاجئ لتوليد بيانات صاخبة تبدو عشوائية دون الحاجة إلى تعقيد العشوائية الحقيقية. ولا يزال يُستخدم أحيانًا في التشفير الحديث في بعض الشيفرات: فالشيفرة نفسها ليست سوى آلية لتوليد مفتاح عشوائي جدًا وطويل إلى ما لا نهاية، يُطبَّق عليه XOR مع المستند.
من الخصائص المثيرة للاهتمام في تشفير XOR أنه متماثل: فتطبيق XOR على أي عدد مع نفسه ينتج 0، وتطبيق XOR على أي عدد مع 0 يُرجع العدد المدخل دون تغيير. لذلك، لفكّ تشفير مستند مشفَّر بـ XOR، طبّق عليه تشفير XOR مرة أخرى باستخدام المفتاح نفسه.
ليس من العملي كتابة اختبار يضمن أن بنيتك struct تحتفظ بمرجع إلى المفتاح بدلًا من نسخه. وبالمثل، ليس من العملي أن تُثبت باختبار أن munge ولا munge_in_place، ولا أيًّا من دوالهما المساعدة، تُخصّص ذاكرة على الكومة. ومع ذلك، ينبغي أن تحاول كتابة حلّك بهذه الطريقة.
ستحتاج إلى كتابة struct Xorcism يحتفظ بمرجع إلى مفتاح. ويجب أن توفّر هذه البنية طريقتين: munge_in_place وmunge. تُعدّل الأولى مخزن بايتات في موضعه. أما الثانية فهي مُهايئ لمكرِّرات: تقبل مكرِّرًا اعتباطيًا للبيانات، وتُرجع مكرِّرًا جديدًا للبيانات.
تواقيع الدوال الأولية في هذا التمرين صحيحة نحويًا إلى حد كبير، لكنها لا تُترجَم: فجزء كبير من الهدف من هذا التمرين هو أن تتعوّد على استخدام فترات الصلاحية والأنواع العامة، لذلك ستحتاج إلى إكمالها بنفسك. وهناك هدف آخر لهذا التمرين هو أن تكتشف تقسيمًا مناسبًا يُمكّنك من تنفيذ كلتا الطريقتين بأقل قدر من تكرار الجهد. لا تتردد في إضافة دوال مساعدة إضافية!
ستكون هذه السمات مفيدة:
يحتوي هذا التمرين على اختبارات إضافية، تتوفّر خلف علامة الميزة io. لتفعيلها، شغّل
cargo test --features io
في هذه الاختبارات، ستحتاج إلى تنفيذ طريقة reader بالتوقيع التالي
fn reader(self, impl Read) -> impl Read
وطريقة writer بالتوقيع التالي
fn writer(self, impl Write) -> impl Write
تُحوّل كل من هذه الدوال بنية Xorcism إلى مُهايئ تدفّق في الاتجاه المناسب. وهي تستخدم هذه السمات:
munge
بسبب استخدام ميزة impl Trait، قد تكون إدارة دورة الحياة صعبة بعض الشيء عند تنفيذ طريقة munge. وقد تجد أنه من الأسهل أن تكتب struct خاصًا بك مع تنفيذ Iterator وأن تُرجع ذلك النوع الملموس، على الأقل كبداية. وفي النهاية، من الجيد أن تحاول تنفيذ الحل باستخدام مُركّبات Iterator مباشرة.
سجّل في Exercism لتتعلّم وتتقن Rust عبر 99 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.