O Java tem operadores para manipular os bits de um byte, short, int, long ou char.
Usa << para deslocar bits para a esquerda e >> para deslocar para a direita.
// Shift two places to the left
0b0000_1011 << 2;
// # => 0b0010_1100
// Shift two places to the right
0b0000_1011 >> 2;
// # => 0b0000_0010
O operador << insere sempre 0s do lado direito.
No entanto, o >> insere o mesmo bit que o bit mais à esquerda (1 se o número for negativo ou 0 se for positivo).
// 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
Usa antes o >>> quando queres inserir 0s ao deslocar para a direita.
// Shift two places to the right, inserting 0s on the left
value >>> 2;
// # => 0010_0000_0000_0000_0000_0000_0000_1001
O operador AND bit a bit (&) recebe dois valores e faz um AND a cada bit.
Compara cada bit do primeiro valor com o bit na mesma posição do segundo valor.
Se ambos forem 1, o bit do resultado é 1.
Caso contrário, o bit do resultado é 0.
0b0110_0101 & 0b0011_1100;
// # => 0b0010_0100
O operador OR bit a bit (|) recebe dois valores e faz um OR a cada bit.
Compara cada bit do primeiro valor com o bit na mesma posição do segundo valor.
Se um dos bits for 1, o bit do resultado é 1.
Caso contrário, é 0.
0b0110_0101 | 0b0011_1100;
// # => 0b0111_1101
O operador XOR bit a bit (^) faz um XOR bit a bit sobre dois valores.
Tal como os operadores AND bit a bit e OR bit a bit, compara cada bit do primeiro valor com o bit na mesma posição do segundo valor.
Se apenas um deles for 1, o bit resultante é 1.
Caso contrário, é 0.
0b0110_0101 ^ 0b0011_1100;
// # => 0b0101_1001
~)Por último, o operador NOT bit a bit (~) inverte cada bit.
Ao contrário dos operadores anteriores, este é um operador unário, que atua apenas sobre um valor.
~0b0110_0101;
// # => 0b1001_1010
O teu amigo acabou de te enviar uma mensagem com um segredo importante. Para que não fosse fácil para os outros lê-la, a mensagem foi cifrada através de uma série de manipulações de bits. Vais precisar de escrever os métodos que ajudam a desencriptar a mensagem.
O primeiro passo para desencriptar a mensagem é desfazer o deslocamento do processo de cifra, deslocando os bits de volta para a direita. Haverá passos seguintes no processo de desencriptação que assumem que são inseridos 0s do lado esquerdo.
Implementa o método Secrets.shiftBack, que recebe um valor e o número de posições a deslocar e efetua o deslocamento.
Secrets.shiftBack(0b1001, 2);
# => 0b0010
De seguida, há alguns bits que precisam de ser colocados a 1.
Implementa o método Secrets.setBits, que recebe um valor e uma máscara e devolve o resultado de colocar a 1 os bits do valor.
Um bit do valor deve ser colocado a 1 quando o bit correspondente na máscara também for 1.
Todos os outros bits devem permanecer inalterados.
Secrets.setBits(0b0110, 0b0101);
# => 0b0111
Alguns bits são invertidos durante a cifra. Será preciso invertê-los de volta para desencriptar a mensagem.
Implementa o método Secrets.flipBits, que recebe um valor e a máscara.
A máscara indica quais os bits do valor a inverter.
Se o bit na máscara for 1, o bit é invertido no valor.
Todos os outros bits permanecem inalterados.
Secrets.flipBits(0b1100, 0b0101);
# => 0b1001
Por último, também há certos bits que desencriptam sempre para 0.
Implementa o método Secrets.clearBits, que recebe um valor e uma máscara.
Os bits em value devem ser colocados a 0 onde o bit na máscara for 1.
Todos os outros bits devem permanecer inalterados.
Secrets.clearBits(0b0110, 0b0101);
# => 0b0010
Inscreve-te no Exercism para aprenderes e dominares Java com 26 conceitos158 exercícios, e mentoria humana real, tudo grátis.