[Resolvido] Problemas rotacionamento de bits em byte

5 respostas
InSeOfKn

Ola!
Como seria o algorítimo de rotacionamento de bits para um byte (8 bits)? Tenho um aqui, mas ele não esta funcionando muito bem pois com alguns testes percebi que ao rotacionar 2 bits para direita e depois rotacionar 2 bits para esquerda nem sempre se volta ao byte original

Segue o algorítimo
public static byte rotateLeft(byte value, int n) {
		return (byte) ((value << n) | (value >> (8 - n)));
	}

	public static byte rotateRight(byte value, int n) {
		return (byte) ((value >> n) | (value << (8 - n)));
	}
e as linhas para o teste
byte i = (byte)(new Random().nextInt(Byte.MAX_VALUE-Byte.MIN_VALUE)+Byte.MIN_VALUE);
		byte x = Criptografador.rotateRight(i, 2);
		byte y = Criptografador.rotateLeft(x, 2);

		System.out.println("Byte sorteado: " + i);
		System.out.println("É igual apos ROR e ROL: " + (y == i));
		System.out.println("Byte em bin: "+Integer.toBinaryString(i));
		System.out.println("Byte apos ROR em bin: " + Integer.toBinaryString(x));
		System.out.println("Byte apos ROL em bin: " + Integer.toBinaryString(y));
Bom espero que vocês saibam o motivo de funcionar com alguns bytes e com outros não, e que possam me ajudar a elaborar um realmente funcional.

Até, e muito obrigado!

5 Respostas

jamirdeajr
Neste link tem um código que deve funcionar, porem 32 bits: [url]http://mindprod.com/jgloss/rotate.html[/url] Reproduzindo aqui, modificando para 8 bits, ele é um pouco diferente do seu pois usa >>> e >> : Note que 1010 >> 2 resulta em 111010 e 1010 >>> 2 resulta em 001010
/**
 * Gira um valor n bits a esquerda.
 *
 * @param value Valor a girar
 * @param n quantos bits girar a esquerda
 * de 0 a 7 bits
 * @return Valor 'girado'
 */
public static byte rotateLeft ( byte value, int n )
   {
   return (byte) (( value << n ) | ( value >>> (8 - n)));
   }

/**
 * Gira um valor n bits a direita.
 *
 * @param value Valor a girar
 * @param n quantos bits girar a direita
 * de 0 a 7 bits
 * @return Valor 'girado'
 */
public static byte rotateRight ( byte value, int n )
   {
   return (byte)(( value >>> n ) | ( value << (8 - n)));
   }
ViniGodoy

Outra dúvida é. O que você quer fazer com o bit do sinal? Rotaciona-lo também?

InSeOfKn

jamirdeajr obrigado pela resposta, mas continua o mesmo problema, ao rotacionar por exemplo 2 a direita e depois 2 a esquerda nem sempre o byte volta ao byte original.

ViniGodoy o que pretendo rotacionando o byte é “embaralhar” os dados uma um array de bytes, portanto não estou interessado no valor decimal do byte e sim que depois de girar para a direita e para esquerda resulte no mesmo byte.
Obs: não pretendo rotacionar a array como uma, e sim cada byte individualmente

Até!

jamirdeajr
Tenta assim:
public static byte rotateLeft ( byte value, int n ) 
{  
   return (byte) (( value << n ) | ( (value & 0xFF) >>> (8 - n)));  
} 
	 
public static byte rotateRight ( byte value, int n )  
{  
   return (byte)(( (value & 0xFF) >>> n ) | ( value << (8 - n)));  
}
Citando Wikipedia "Bitwise operation": Shifts in Java

In Java, all integer types are signed, and the "<<" and ">>" operators perform arithmetic shifts. Java adds the operator ">>>" to perform logical right shifts, but because the logical and arithmetic left-shift operations are identical, there is no "<<<" operator in Java. These general rules are affected in several ways by the default type promotions; for example, because the eight-bit type byte is promoted to int in shift-expressions,[4] the expression "b >>> 2" effectively performs an arithmetic shift of the byte value b instead of a logical shift. Such effects can be mitigated by judicious use of casts or bitmasks; for example, "(b & 0xFF) >>> 2" effectively results in a logical shift.

InSeOfKn

Muito obrigado! funcionou perfeitamente!
Só não intendi porque que fazendo (value & 0xFF) mudou algo, pois até onde eu sei se eu fizer um END com 11111111 o valor não vai se alterar.
Bom, vou vou ler com mais calma a citação para ver se intendo (a tradução do google tradutor ficou péssima).

Até!

Criado 8 de julho de 2011
Ultima resposta 10 de jul. de 2011
Respostas 5
Participantes 3