رازها

رازها

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

مقدمه

عملیات بیتی

عملیات بیتی به ما امکان می‌دهد ارقام جداگانه را درون اعداد دودویی دستکاری کنیم.

Elm چندین عملگر بیتی را در ماژول Bitwise خود ارائه می‌دهد.

عملیات پایه

تغییر دادن بیت‌های تک‌تک یک عدد را ماسک‌کردن می‌نامند. ماسک عددی است که بیت‌های مشخصی در آن به شیوه‌ای خاص تنظیم شده‌اند تا با استفاده از عملگرهای بیتی مانند and، or و xor، عدد دیگری را دستکاری کنند.

and

and با نگه داشتن فقط بیت‌هایی که در هر دو عدد 1 هستند، دو عدد را با هم ترکیب می‌کند. این کار برای بررسی اینکه یک بیت مشخص تنظیم شده است یا نه مفید است. برای مثال، برای بررسی اینکه بیت چهارم یک عدد روی 1 تنظیم شده است یا نه، آن را با ماسکی به مقدار 01000 (8 در مبنای ده) and کنید و ببینید که آیا نتیجه صفر نیست:

Bitwise.and 13 8 --> 8
--  13 = 01101
--   8 = 01000
-- and = 01000 = 8
or

or دو عدد را با هم ترکیب می‌کند و هر بیتی را که در یکی از آن دو یا در هر دو عدد 1 باشد روی 1 تنظیم می‌کند. این کار برای تنظیم یک بیت مشخص روی 1 مفید است. برای مثال، برای تنظیم بیت دوم در 10101، آن را با ماسک 00010 or کنید:

Bitwise.or 21 2 --> 23
-- 21 = 10101
--  2 = 00010
-- or = 10111 = 23
یای انحصاری (xor)

xor دو عدد را با هم ترکیب می‌کند و هر بیتی را که در یکی از دو عدد 1 و در دیگری 0 باشد روی 1 تنظیم می‌کند. این کار برای وارونه کردن یک بیت به مقدار مخالفش مفید است:

Bitwise.xor 20 5 --> 17
--  20 = 10100
--   5 = 00101
-- xor = 10001 = 17
متمم

complement هر بیت یک عدد را وارونه می‌کند (0 به 1 تبدیل می‌شود و 1 به 0).

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

Bitwise.complement 21 --> -22
--         21 = 00000000000000000000000000010101
-- complement = 11111111111111111111111111101010 = -22
جابه‌جایی بیتی

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

shiftLeftBy بیت‌ها را به چپ می‌برد و از سمت راست با 0 پر می‌کند. برای مثال، برای جابه‌جا کردن 21 به اندازه‌ی ۳ خانه به چپ:

Bitwise.shiftLeftBy 3 21 --> 168
--  21 = 10101
-- shiftLeftBy 3 = 10101000 = 168

این معادل عبارت 21 * 2^3 = 21 * 2 * 2 * 2 = 168 است.

shiftRightBy: بیت‌ها را به راست می‌برد:

Bitwise.shiftRightBy 2 21 --> 5
--  21 = 10101
-- shiftRightBy 2 = 00101 = 5

جابه‌جا کردن به اندازه‌ی ۲ خانه به راست، همان تقسیم صحیح بر ۴ است.

توجه کنید که این تابع هر مقداری که در چپ‌ترین بیت قرار دارد را عیناً تکرار می‌کند. بنابراین اعداد منفی منفی می‌مانند:

Bitwise.shiftRightBy 3 -21 --> -3
--  -21 = 111...101011
-- shiftRightBy 3 = 111...11101 = -3

اگر می‌خواهید به راست جابه‌جا کنید و با صفر پر کنید، از shiftRightZfBy استفاده کنید:

Bitwise.shiftRightZfBy 3 -21 --> 536870909
--  -21 = 111...101011
-- shiftRightZfBy 3 = 00111...11101 = 536870909

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

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

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

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

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

shiftBack 2 42 --> 10

2. چند بیت را تنظیم کنید

در گام بعد، چند بیت وجود دارد که باید روی 1 تنظیم شوند.

تابع setBits را پیاده‌سازی کنید که یک «ماسک» و یک مقدار می‌گیرد و نتیجه‌ی تنظیم بیت‌های آن مقدار روی 1 را برمی‌گرداند. هر بیتی از مقدار که بیت متناظرش در ماسک هم 1 باشد، باید روی 1 تنظیم شود. بقیه‌ی بیت‌ها باید بدون تغییر بمانند.

setBits 66 212 --> 64

3. بیت‌های مشخصی را وارونه کنید

هنگام رمزنگاری، بعضی بیت‌ها وارونه می‌شوند. برای رمزگشایی پیام باید دوباره وارونه شوند.

تابع flipBits را پیاده‌سازی کنید که یک ماسک و یک مقدار می‌گیرد. ماسک مشخص می‌کند که کدام بیت‌های مقدار وارونه شوند. اگر بیت متناظر در ماسک 1 باشد، آن بیت در مقدار وارونه می‌شود. بقیه‌ی بیت‌ها بدون تغییر می‌مانند.

flipBits 23 157 --> 138

4. بیت‌های مشخصی را پاک کنید

بیت‌هایی هم وجود دارند که همیشه به ۰ رمزگشایی می‌شوند.

تابع clearBits را پیاده‌سازی کنید که یک ماسک و یک مقدار می‌گیرد. بیت‌های value باید همان‌جا که بیت متناظر در ماسک ۱ است، روی ۰ تنظیم شوند. بقیه‌ی بیت‌ها باید بدون تغییر بمانند.

clearBits 2 15 --> 13

5. رمزگشایی یک پیام

حالا که همه‌ی توابع لازم را دارید، می‌توانید پیام دوستتان را رمزگشایی کنید. تابع decrypt را پیاده‌سازی کنید که عملیات زیر را انجام می‌دهد:

  1. تنظیم بیت‌ها بر اساس سال تولد دوستتان (۱۹۹۶)
  2. وارونه کردن نتیجه با سالی که اولین بار همدیگر را دیدید (۲۰۰۹)
  3. جابه‌جایی بیت‌ها به عقب به تعداد کلاس‌هایی که با هم دارید (۵)
  4. پاک کردن بیت اول و پنجم.
decrypt 380182 --> 11840

لطفاً decrypt را با همان توابعی بنویسید که در کارهای قبلی پیاده‌سازی کردید.

ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Elm Exercism

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

در Exercism ثبت‌نام کنید تا Elm را همراه با 28 مفهوم110 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.