رازها

رازها

تمرین یادگیری

مقدمه

Crystal برای دستکاری Int در سطح دودویی، عملگرهای بیتی دارد.

عملگرهای جابه‌جایی

Crystal عملگرهای جابه‌جایی دارد که بیت‌ها را به چپ (<<) یا راست (>>) جابه‌جا می‌کنند.

جابه‌جایی به چپ(<<)

عملگر جابه‌جایی به چپ (<<) بیت‌ها را به چپ جابه‌جا می‌کند. مقداری که باید جابه‌جا شود در سمت چپ و تعداد مکان‌های جابه‌جایی در سمت راست مشخص می‌شود.

0b0010 << 1
# => 0b0100

0b0010 << 2
# => 0b1000

اگر عدد منفی باشد، در عوض به راست جابه‌جا می‌شود.

0b0010 << -1
# => 0b0001

جابه‌جایی به راست(>>)

عملگر جابه‌جایی به راست (>>) بیت‌ها را به راست جابه‌جا می‌کند. مانند عملگر جابه‌جایی به چپ، مقداری که باید جابه‌جا شود در سمت چپ و تعداد مکان‌های جابه‌جایی در سمت راست مشخص می‌شود.

0b0100 >> 1
# => 0b0010

0b0100 >> 2
# => 0b0001

و به همین ترتیب، اگر عدد منفی باشد، عملگر به چپ جابه‌جا می‌شود.

0b0100 >> -1
# => 0b1000

عملگرهای دوتایی

Crystal سه عملگر دوتایی (&، |، ^) و یک عملگر ~ برای انجام عملیات بیتی دارد.

و بیتی(&)

عملگر دوتایی «و» (&) یک عملیات «و» بیتی روی دو مقدار انجام می‌دهد. هر بیت در مقدار اول را با بیت در همان موقعیت در مقدار دوم مقایسه می‌کند. اگر هر دو بیت ۱ باشند، بیت حاصل روی ۱ تنظیم می‌شود. در غیر این صورت، روی ۰ تنظیم می‌شود.

0b0011 & 0b1010
# => 0b0010

یا بیتی(|)

عملگر دوتایی «یا» (|) یک عملیات «یا» بیتی روی دو مقدار انجام می‌دهد. همچنین هر بیت در مقدار اول را با بیت در همان موقعیت در مقدار دوم مقایسه می‌کند. اگر هر یک از بیت‌ها ۱ باشد، بیت حاصل روی ۱ تنظیم می‌شود. در غیر این صورت، روی ۰ تنظیم می‌شود.

0b0011 | 0b1010
# => 0b1011

یا انحصاری(^)

عملگر دوتایی «یا انحصاری» (^) یک عملیات «یا انحصاری» بیتی انجام می‌دهد. مانند عملگرهای بیتی «و» و «یا»، هر بیت از مقدار اول را با بیت در همان موقعیت در مقدار دوم مقایسه می‌کند. اگر فقط یکی از آن‌ها ۱ باشد، بیت حاصل ۱ است. در غیر این صورت، ۰ است.

0b0011 ^ 0b1010
# => 0b1001

نقیض بیتی(~)

در نهایت، عملگر نقیض بیتی (~) هر یک از بیت‌های مقدار را معکوس می‌کند. برخلاف سایر عملگرهای دوتایی، این یک عملگر یکانی است که فقط روی مقدار سمت راست عمل می‌کند.

~0b1110_0010
# => 0b0001_1101

دستورالعمل‌ها

دوستتان همین حالا پیامی همراه با یک راز مهم برایتان فرستاده است. چون نمی‌خواهد خواندنش برای دیگران آسان باشد، پیام با یک رشته دستکاری بیتی رمزنگاری شده است. باید برنامه‌ای بنویسید که به رمزگشایی پیام کمک کند.

1. بیت‌ها را به عقب جابه‌جا کنید

اولین گام در رمزگشایی پیام این است که جابه‌جایی انجام‌شده در فرایند رمزنگاری را با جابه‌جا کردن بیت‌ها به سمت چپ خنثی کنیم. تعداد جاهایی که باید جابه‌جا شوند، از پیامی به پیام دیگر می‌تواند متفاوت باشد.

متد Secrets.shift_back را پیاده‌سازی کنید که یک مقدار و تعداد جاهای جابه‌جایی به سمت چپ را می‌گیرد.

Secrets.shift_back(0b0001, 2)
# => 0b0100

2. یک ماسک بیتی را اعمال کنید

گام بعدی، اعمال یک ماسک بیتی برای استخراج مقدار بیت‌های مشخصی است. ماسک با انجام یک AND بیتی میان مقدار و ماسک اعمال می‌شود.

متد Secrets.apply_mask را پیاده‌سازی کنید که یک مقدار می‌گیرد و ماسکی را اعمال می‌کند.

Secrets.apply_mask(0b0110, 0b0101)
# => 0b0100

3. برخی از بیت‌ها را تنظیم کنید

جابه‌جا کردن بیت‌ها به سمت چپ، چند بیت ۰ تازه اضافه کرده است. بعضی از این بیت‌های تازه باید به ۱ تبدیل شوند. OR بیتی برای تبدیل بیت‌های خاصی به ۱ و در همان حال حفظ بقیه به کار می‌آید.

متد Secrets.set_bits را پیاده‌سازی کنید که دو مقدار می‌گیرد و یک OR بیتی انجام می‌دهد.

Secrets.set_bits(0b0110, 0b0101)
# => 0b111

4. وارون کردن XOR

بخشی از فرایند رمزنگاری، یک XOR با یک مقدار توافق‌شده اعمال می‌کند. برای بازگشت به مقدار اصلی، کافی است مقدار رمزنگاری‌شده را دوباره با همان مقدار توافق‌شده XOR کنیم. اما به دلیل یک سوءتفاهم، دوستتان پیش از اعمال XOR بیت‌های مقدار توافق‌شده را وارونه کرده است (یعنی یک NOT بیتی روی مقدار توافق‌شده اعمال کرده است).

متد Secrets.reverse_xor را پیاده‌سازی کنید که مقدار رمزنگاری‌شده و مقدار توافق‌شده را می‌گیرد و مقدار اصلی را محاسبه می‌کند.

Secrets.reverse_xor(0b1100, 0b0101)
# => 0b(0110)
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Crystal Exercism

آماده‌اید رازها را شروع کنید؟

در Exercism ثبت‌نام کنید تا Crystal را همراه با 26 مفهوم142 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.