عملیات بیتی به ما امکان میدهد ارقام جداگانه را درون اعداد دودویی دستکاری کنیم.
Elm چندین عملگر بیتی را در ماژول Bitwise خود ارائه میدهد.
تغییر دادن بیتهای تکتک یک عدد را ماسککردن مینامند.
ماسک عددی است که بیتهای مشخصی در آن به شیوهای خاص تنظیم شدهاند تا با استفاده از عملگرهای بیتی مانند and، or و xor، عدد دیگری را دستکاری کنند.
and با نگه داشتن فقط بیتهایی که در هر دو عدد 1 هستند، دو عدد را با هم ترکیب میکند.
این کار برای بررسی اینکه یک بیت مشخص تنظیم شده است یا نه مفید است.
برای مثال، برای بررسی اینکه بیت چهارم یک عدد روی 1 تنظیم شده است یا نه، آن را با ماسکی به مقدار 01000 (8 در مبنای ده) and کنید و ببینید که آیا نتیجه صفر نیست:
Bitwise.and 13 8 --> 8
-- 13 = 01101
-- 8 = 01000
-- and = 01000 = 8
or دو عدد را با هم ترکیب میکند و هر بیتی را که در یکی از آن دو یا در هر دو عدد 1 باشد روی 1 تنظیم میکند.
این کار برای تنظیم یک بیت مشخص روی 1 مفید است.
برای مثال، برای تنظیم بیت دوم در 10101، آن را با ماسک 00010 or کنید:
Bitwise.or 21 2 --> 23
-- 21 = 10101
-- 2 = 00010
-- or = 10111 = 23
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
دوستتان همین حالا پیامی با یک راز مهم برایتان فرستاده است. او نمیخواست خواندن آن برای دیگران آسان باشد، بنابراین پیام با انجام زنجیرهای از دستکاریهای بیتی رمزنگاری شده است. شما باید توابعی بنویسید که به رمزگشایی پیام کمک کنند.
اولین گام در رمزگشایی پیام این است که جابهجایی انجامشده در فرایند رمزنگاری را خنثی کنید و بیتها را به سمت راست برگردانید.
در ادامهی فرایند رمزگشایی گامهای دیگری هم وجود دارد که فرض میکنند 0ها از سمت چپ وارد میشوند.
تابع shiftBack را پیادهسازی کنید که تعداد جاهای جابهجایی و یک مقدار را میگیرد و جابهجایی را انجام میدهد.
shiftBack 2 42 --> 10
در گام بعد، چند بیت وجود دارد که باید روی 1 تنظیم شوند.
تابع setBits را پیادهسازی کنید که یک «ماسک» و یک مقدار میگیرد و نتیجهی تنظیم بیتهای آن مقدار روی 1 را برمیگرداند.
هر بیتی از مقدار که بیت متناظرش در ماسک هم 1 باشد، باید روی 1 تنظیم شود.
بقیهی بیتها باید بدون تغییر بمانند.
setBits 66 212 --> 64
هنگام رمزنگاری، بعضی بیتها وارونه میشوند. برای رمزگشایی پیام باید دوباره وارونه شوند.
تابع flipBits را پیادهسازی کنید که یک ماسک و یک مقدار میگیرد.
ماسک مشخص میکند که کدام بیتهای مقدار وارونه شوند.
اگر بیت متناظر در ماسک 1 باشد، آن بیت در مقدار وارونه میشود.
بقیهی بیتها بدون تغییر میمانند.
flipBits 23 157 --> 138
بیتهایی هم وجود دارند که همیشه به ۰ رمزگشایی میشوند.
تابع clearBits را پیادهسازی کنید که یک ماسک و یک مقدار میگیرد.
بیتهای value باید همانجا که بیت متناظر در ماسک ۱ است، روی ۰ تنظیم شوند.
بقیهی بیتها باید بدون تغییر بمانند.
clearBits 2 15 --> 13
حالا که همهی توابع لازم را دارید، میتوانید پیام دوستتان را رمزگشایی کنید.
تابع decrypt را پیادهسازی کنید که عملیات زیر را انجام میدهد:
decrypt 380182 --> 11840
لطفاً decrypt را با همان توابعی بنویسید که در کارهای قبلی پیادهسازی کردید.