زبان Java برای دستکاری بیتهای یک byte، short، int، long یا char عملگرهایی دارد.
از << برای شیفت دادن بیتها به چپ و از >> برای شیفت دادن به راست استفاده کنید.
// Shift two places to the left
0b0000_1011 << 2;
// # => 0b0010_1100
// Shift two places to the right
0b0000_1011 >> 2;
// # => 0b0000_0010
عملگر << همیشه در سمت راست صفر درج میکند.
اما >> همان بیتی را درج میکند که در چپترین موقعیت قرار دارد (اگر عدد منفی باشد ۱ و اگر مثبت باشد ۰).
// Shift 2 places to the right preserves the sign
// This is a negative value, whose binary representation is
// 1000_0000_0000_0000_0000_0000_0010_0110
int value = -0x7FFFFFDA;
// Shift two places to the right, preserving the sign bit
value >> 2;
// # => 1110_0000_0000_0000_0000_0000_0000_1001
وقتی هنگام شیفت دادن به راست باید صفر درج شود، بهجای آن از >>> استفاده کنید.
// Shift two places to the right, inserting 0s on the left
value >>> 2;
// # => 0010_0000_0000_0000_0000_0000_0000_1001
عملگر AND بیتی (&) دو مقدار میگیرد و روی هر بیت یک عمل AND انجام میدهد.
هر بیت از مقدار اول را با بیتی در همان موقعیت از مقدار دوم مقایسه میکند.
اگر هر دو ۱ باشند، بیت نتیجه ۱ میشود.
در غیر این صورت، بیت نتیجه ۰ است.
0b0110_0101 & 0b0011_1100;
// # => 0b0010_0100
عملگر OR بیتی (|) دو مقدار میگیرد و روی هر بیت یک عمل OR انجام میدهد.
هر بیت از مقدار اول را با بیتی در همان موقعیت از مقدار دوم مقایسه میکند.
اگر یکی از آن دو بیت ۱ باشد، بیت نتیجه ۱ میشود.
در غیر این صورت، ۰ است.
0b0110_0101 | 0b0011_1100;
// # => 0b0111_1101
عملگر XOR بیتی (^) روی دو مقدار یک عمل XOR بیتی انجام میدهد.
مانند عملگرهای AND بیتی و OR بیتی، هر بیت از مقدار اول را با بیتی در همان موقعیت از مقدار دوم مقایسه میکند.
اگر تنها یکی از آن دو ۱ باشد، بیت حاصل ۱ میشود.
در غیر این صورت، ۰ است.
0b0110_0101 ^ 0b0011_1100;
// # => 0b0101_1001
~)در پایان، عملگر NOT بیتی (~) هر بیت را وارونه میکند.
برخلاف عملگرهای قبلی، این یک «عملگر یگانی» است که تنها روی یک مقدار عمل میکند.
~0b0110_0101;
// # => 0b1001_1010
دوستتان همین حالا پیامی همراه با یک راز مهم برایتان فرستاده است. او نمیخواست خواندن آن برای دیگران آسان باشد، بنابراین پیام با انجام مجموعهای از دستکاریهای بیتی رمزنگاری شده است. برای رمزگشایی پیام باید متدهایی بنویسید.
اولین گام در رمزگشایی پیام این است که شیفت انجامشده در فرایند رمزنگاری را با شیفت دادن بیتها به سمت راست خنثی کنید. در ادامهی فرایند رمزگشایی گامهای دیگری هم هست که فرض میکند صفرها از سمت چپ وارد میشوند.
متد Secrets.shiftBack را پیادهسازی کنید که یک مقدار و تعداد جایگاههای شیفت را میگیرد و شیفت را انجام میدهد.
Secrets.shiftBack(0b1001, 2);
# => 0b0010
در گام بعد، بیتهایی هستند که باید روی ۱ تنظیم شوند.
متد Secrets.setBits را پیادهسازی کنید که یک مقدار و یک ماسک میگیرد و نتیجهی تنظیم بیتهای مقدار روی ۱ را برمیگرداند.
بیتی از مقدار که بیت متناظرش در ماسک هم ۱ است، باید روی ۱ تنظیم شود.
سایر بیتها باید بدون تغییر بمانند.
Secrets.setBits(0b0110, 0b0101);
# => 0b0111
بعضی بیتها در هنگام رمزنگاری وارونه میشوند. برای رمزگشایی پیام باید دوباره وارونه شوند.
متد Secrets.flipBits را پیادهسازی کنید که یک مقدار و یک ماسک میگیرد.
ماسک مشخص میکند کدام بیتهای مقدار وارونه شوند.
اگر بیتی در ماسک ۱ باشد، بیت متناظر در مقدار وارونه میشود.
سایر بیتها بدون تغییر میمانند.
Secrets.flipBits(0b1100, 0b0101);
# => 0b1001
در پایان، بیتهای مشخصی هم هستند که همیشه به ۰ رمزگشایی میشوند.
متد Secrets.clearBits را پیادهسازی کنید که یک مقدار و یک ماسک میگیرد.
بیتهای value باید ۰ شوند، هر جا که بیت متناظر در ماسک ۱ است.
سایر بیتها باید بدون تغییر بمانند.
Secrets.clearBits(0b0110, 0b0101);
# => 0b0010