یک «آداپتور جریانی» بنویسید که ارجاعی به یک کلید در خود نگه میدارد و آن را با دادههای دلخواه بهصورت بیتی XOR میکند.
XOR یک عملیات دودویی بنیادی است: برای هر بیت در ورودیها، اگر بیتهای ورودی متفاوت باشند، بیت متناظر در خروجی را 1 قرار دهید. اگر هر دو ورودی 1 باشند یا هر دو 0 باشند، بیت متناظر خروجی 0 است.
وقتی سندی با یک کلید XOR میشود، کلید به تعداد دفعات لازم تکرار میشود و سند خروجیای با طولی برابر سند ورودی تولید میکند.
XOR کردن یک سند با یک کلید، تا همین اواخر، یعنی تا اوایل دههی ۱۹۰۰، در رمزنگاری به کار میرفت. هرچند این روش برای پنهان کردن داده کاملاً منسوخ شده است، میتواند بهطرز شگفتانگیزی برای تولید دادههای نویزی و بهظاهر تصادفی مفید باشد، بدون آنکه به دردسر تصادفیبودن واقعی نیاز داشته باشید. در رمزنگاری مدرن هم گاهی برای برخی رمزها از آن استفاده میشود: خود رمز فقط سازوکاری است برای تولید یک کلید بسیار تصادفی و بینهایت طولانی که با سند XOR میشود.
یک ویژگی جالب رمزنگاری XOR این است که متقارن است: XOR کردن هر عددی با خودش 0 میدهد و XOR کردن هر عددی با 0 همان عدد ورودی را بدون تغییر برمیگرداند. پس برای رمزگشایی سندی که با XOR رمزنگاری شده، آن را دوباره با همان کلید رمزنگاری کنید.
نوشتن آزمونی که تضمین کند ساختار شما بهجای کپی کردن کلید، ارجاعی به آن را نگه میدارد عملی نیست. به همین ترتیب، اثبات با آزمون اینکه نه munge و نه munge_in_place و نه هیچیک از توابع کمکی آنها روی هیپ حافظه تخصیص نمیدهند هم عملی نیست. با این حال، باید تلاش کنید راهحل خود را به همین شکل بنویسید.
شما باید یک struct Xorcism بنویسید که ارجاعی به یک کلید در خود نگه میدارد. این ساختار باید دو متد ارائه دهد: munge_in_place و munge. متد اول یک بافر بایتی را درجا تغییر میدهد. متد دوم یک آداپتور «تکرارگر» است: هر تکرارگر دلخواهی از دادهها را میپذیرد و یک تکرارگر جدید از دادهها بازمیگرداند.
امضاهای استاب این تمرین از نظر نحوهی نگارش عمدتاً درستاند، اما کامپایل نمیشوند: بخش بزرگی از هدف این تمرین، آشنا شدن شما با استفاده از «طول عمر»ها و «جنریک»هاست، بنابراین باید خودتان آنها را پر کنید. هدف دیگر این تمرین، یافتن تجزیهی مناسبی است که به شما امکان دهد هر دو متد را با کمترین دوبارهکاری پیادهسازی کنید. از اضافه کردن توابع کمکی بیشتر نترسید!
traitهای مفیداین traitها مفید خواهند بود:
این تمرین آزمونهای امتیاز دارد که پشت پرچم ویژگی io قرار گرفتهاند. برای فعال کردن آنها، این را اجرا کنید
cargo test --features io
برای این آزمونها باید متدی به اسم reader با این امضا پیادهسازی کنید
fn reader(self, impl Read) -> impl Read
و متدی به اسم writer با این امضا
fn writer(self, impl Write) -> impl Write
هر یک از این توابع، ساختار Xorcism را به یک آداپتور جریانی در جهت مناسب تبدیل میکنند. آنها از این traitها استفاده میکنند:
munge
به دلیل استفاده از ویژگی impl Trait، مدیریت طول عمر ممکن است هنگام پیادهسازی متد munge کمی پیچیده باشد. ممکن است برایتان آسانتر باشد که یک struct از خودتان با یک پیادهسازی از Iterator بنویسید و همان نوع مشخص را برگردانید، حداقل برای شروع. در نهایت، ایدهی خوبی است که راهحل را مستقیماً با ترکیبکنندههای Iterator پیادهسازی کنید.