Respuesta
Intentar obtener este libro, hay capítulo entero acerca de los bits de reversión: Hacker's Delight. Pero compruebe el contenido primero si esto le conviene.
La manera más rápida, pero también la que requiere más espacio, es una búsqueda, en la que cada valor posible de un byte (256 si se usa para todo el rango) está asociado con su equivalente "invertido".
Si sólo tiene un par de dichos bytes de manejar, los operadores bit a bit van a hacer, pero que va a ser más lento, tal vez algo como:
function reverseBits($in) {
$out = 0;
if ($in & 0x01) $out |= 0x80;
if ($in & 0x02) $out |= 0x40;
if ($in & 0x04) $out |= 0x20;
if ($in & 0x08) $out |= 0x10;
if ($in & 0x10) $out |= 0x08;
if ($in & 0x20) $out |= 0x04;
if ($in & 0x40) $out |= 0x02;
if ($in & 0x80) $out |= 0x01;
return $out;
}
Históricamente, he encontrado que tener una tabla de búsqueda de 256 bytes es la forma más rápida de lograrlo, ya que solo es una búsqueda. 256 bytes no es mucho espacio para dedicar a algo como esto si necesita ser rápido. Aunque la función reverseBits anterior es tan pequeña y ajustada como puedes obtener el código sin tener que buscar. También para una optimización pequeña, puede cambiar el primer {$ out | = 0x80;} a {$ out = 0x80;} como sabe la primera vez que está haciendo un OR con 0. – skirmish
@skirmish, de acuerdo, tendería a use la matriz de búsqueda en la mayoría de los casos. Una solución intermedia sería tener una matriz más pequeña, de 4 bits, y hacer dos búsquedas con la multiplicación/división asociada para el bit-quad más a la izquierda). Esta forma de hacer también se puede usar para tratar con decir enteros en lugar de bytes. (La desventaja del enfoque de búsqueda es que su requerimiento de espacio crece exponencialmente, por lo que el approo codificado es lineal (con respecto a la cantidad de bits). – mjv
El enfoque recta hacia adelante es llevar a cabo 8 máscaras, 8 gira y 7 adiciones:
$blah = $blah & 128 >> 7 + $blah & 64 >> 5 + $blah & 32 >> 3 + $blah & 16 >> 1 + $blah & 8 << 1 + $blah & 4 << 3 + $blah & 2 << 5 + $blah & 1 << 7;
¿Eso tiene dos votos positivos? –
@Kinopiko: 3 votos ascendentes, con el mío. una mejor solución. ¡Publique y obtendrá mi voto también! – Seb
Bueno, está respondiendo la pregunta :-) –
Si ya tiene los bits en la forma de una cadena, utilice strrev.
De lo contrario, convierta primero el byte a su representación binaria usando decbin, luego invierta usando strrev, luego vuelva al byte (si es necesario) usando bindec.
La mejor respuesta IMO que funcionará para casos generales. Esos cambios de bit, rotación, etc. solo se enfocan en el valor de ejemplo proporcionado y no funcionarán para cadenas binarias aleatorias. – Lukman
+1 Esto es lo que habría sugerido si no hubiera fracasado en la comprensión inicial. –
Tengo mucha curiosidad sobre por qué he sido votado aquí ... – Konamiman
Consulte la sección sobre secuencias de bits inversas en Bit Twiddling Hacks. Debería ser fácil adaptar una de las técnicas a PHP.
Aunque probablemente no sea práctico para PHP, hay una particularmente fascinante con 3 operaciones de 64 bits:
unsigned char b; // reverse this (8-bit) byte
b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
¿Puede explicar qué significa "ULL" aquí? – Mask
@mask que es un unsigned long long, el sufijo le dice al compilador que lo que procede es un literal entero sin signo de 64 bits. – PeterAllenWebb
¿por qué es una solución si no es práctico para php? – denoise
no estoy de acuerdo con el uso de una tabla de consulta como (para los números enteros más grandes) la cantidad de tiempo necesario para cargarlo en la memoria supera el rendimiento del procesamiento.
También utilizo un enfoque a nivel de bit de enmascaramiento de una solución de O (log n), que se parece:
MASK = onescompliment of 0
while SIZE is greater than 0
SIZE = SIZE shiftRight 1
MASK = MASK xor (MASK shiftLeft SIZE)
output = ((output shiftRight SIZE) bitwiseAnd MASK) bitwiseOR ((onescompliment of MASK) bitwiseAnd (output shfitLeft SIZE))
La ventaja de este enfoque es que maneja el tamaño de su número entero como argumento
en php ejemplo de esta situación:
function bitrev($bitstring, $size){
$mask = ~0;
while ($size > 0){
$size = $size >> 1;
$mask = $mask^($mask << $size);
$bitstring = (($bitstring >> $size) & $mask) | ((~$mask) & ($bitstring << $size));
}
}
menos que lo arruiné mi php algún lugar :(
si realiza la operación solo una vez, una tabla de búsqueda es incorrecta. Pero si se trata de una operación frecuente, debe superar cualquier otro enfoque. –
Esto es O (n) con la longitud del bit. Solo piense en la entrada como una pila y escriba en la pila de salida.
Mi intento de escribir esto en PHP.
function bitrev ($inBits, $bitlen){
$cloneBits=$inBits;
$inBits=0;
$count=0;
while ($count < $bitlen){
$count=$count+1;
$inBits=$inBits<<1;
$inBits=$inBits|($cloneBits & 0x1);
$cloneBits=$cloneBits>>1;
}
return $inBits;
}
Algunas personas han sugerido una tabla de búsqueda, mientras que yo he estado haciendo una:
[
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF,
][$byte]
y aquí está una versión de caracteres:
[
"\x00", "\x80", "\x40", "\xC0", "\x20", "\xA0", "\x60", "\xE0", "\x10", "\x90", "\x50", "\xD0", "\x30", "\xB0", "\x70", "\xF0",
"\x08", "\x88", "\x48", "\xC8", "\x28", "\xA8", "\x68", "\xE8", "\x18", "\x98", "\x58", "\xD8", "\x38", "\xB8", "\x78", "\xF8",
"\x04", "\x84", "\x44", "\xC4", "\x24", "\xA4", "\x64", "\xE4", "\x14", "\x94", "\x54", "\xD4", "\x34", "\xB4", "\x74", "\xF4",
"\x0C", "\x8C", "\x4C", "\xCC", "\x2C", "\xAC", "\x6C", "\xEC", "\x1C", "\x9C", "\x5C", "\xDC", "\x3C", "\xBC", "\x7C", "\xFC",
"\x02", "\x82", "\x42", "\xC2", "\x22", "\xA2", "\x62", "\xE2", "\x12", "\x92", "\x52", "\xD2", "\x32", "\xB2", "\x72", "\xF2",
"\x0A", "\x8A", "\x4A", "\xCA", "\x2A", "\xAA", "\x6A", "\xEA", "\x1A", "\x9A", "\x5A", "\xDA", "\x3A", "\xBA", "\x7A", "\xFA",
"\x06", "\x86", "\x46", "\xC6", "\x26", "\xA6", "\x66", "\xE6", "\x16", "\x96", "\x56", "\xD6", "\x36", "\xB6", "\x76", "\xF6",
"\x0E", "\x8E", "\x4E", "\xCE", "\x2E", "\xAE", "\x6E", "\xEE", "\x1E", "\x9E", "\x5E", "\xDE", "\x3E", "\xBE", "\x7E", "\xFE",
"\x01", "\x81", "\x41", "\xC1", "\x21", "\xA1", "\x61", "\xE1", "\x11", "\x91", "\x51", "\xD1", "\x31", "\xB1", "\x71", "\xF1",
"\x09", "\x89", "\x49", "\xC9", "\x29", "\xA9", "\x69", "\xE9", "\x19", "\x99", "\x59", "\xD9", "\x39", "\xB9", "\x79", "\xF9",
"\x05", "\x85", "\x45", "\xC5", "\x25", "\xA5", "\x65", "\xE5", "\x15", "\x95", "\x55", "\xD5", "\x35", "\xB5", "\x75", "\xF5",
"\x0D", "\x8D", "\x4D", "\xCD", "\x2D", "\xAD", "\x6D", "\xED", "\x1D", "\x9D", "\x5D", "\xDD", "\x3D", "\xBD", "\x7D", "\xFD",
"\x03", "\x83", "\x43", "\xC3", "\x23", "\xA3", "\x63", "\xE3", "\x13", "\x93", "\x53", "\xD3", "\x33", "\xB3", "\x73", "\xF3",
"\x0B", "\x8B", "\x4B", "\xCB", "\x2B", "\xAB", "\x6B", "\xEB", "\x1B", "\x9B", "\x5B", "\xDB", "\x3B", "\xBB", "\x7B", "\xFB",
"\x07", "\x87", "\x47", "\xC7", "\x27", "\xA7", "\x67", "\xE7", "\x17", "\x97", "\x57", "\xD7", "\x37", "\xB7", "\x77", "\xF7",
"\x0F", "\x8F", "\x4F", "\xCF", "\x2F", "\xAF", "\x6F", "\xEF", "\x1F", "\x9F", "\x5F", "\xDF", "\x3F", "\xBF", "\x7F", "\xFF",
][ord($byte)];
- 1. ¿Cómo puedo invertir bits de un byte sin signo en Java?
- 2. Invertir mapas de bits colores
- 3. ¿Cómo convertir un byte en bits?
- 4. Cómo invertir en bits AND (&) en C?
- 5. Usando Python ¿Cómo puedo leer los bits en un byte?
- 6. Conversión de una representación de bits en un byte
- 7. Gdiplus :: ¿Mapa de bits a matriz BYTE?
- 8. Python: La extracción de los bits de un byte
- 9. ¿Cómo obtener un solo byte de BitArray (sin byte [])?
- 10. ¿Cómo funciona este código para invertir bits en número?
- 11. Entero a byte con un número dado de bits establecidos
- 12. reemplazar byte de 32 bits número
- 13. Intercambio de par de bits en un byte
- 14. Java Iterate Bits en Byte Array
- 15. Renderizar un byte [] como mapa de bits en Android
- 16. Cómo usar 'System.Security.Cryptography.AesManaged' para cifrar un byte []?
- 17. Construcción una expresión lógica que contará bits en un byte
- 18. ¿Puedo 'invertir' un bool?
- 19. ¿Cómo se lee un byte de archivo por byte en Python y cómo imprimir un bytelist como un binario?
- 20. C#, bits y bytes - ¿Cómo recupero los valores de bit de un byte?
- 21. Intercambiar cada par de bits en el byte
- 22. ¿Cómo se configuran solo ciertos bits de un byte en C sin afectar el resto?
- 23. Si el byte es un número entero de 8 bits, ¿cómo podemos establecerlo en 255?
- 24. Cómo invertir String.fromCharCode?
- 25. Cómo leer un entero de un byte []
- 26. ¿Cómo leer bits de un archivo?
- 27. Invertir orden de un conjunto de elementos
- 28. Representación de un Kilo/Mega/Tera Byte
- 29. Cómo invertir System.loadLibrary en Java
- 30. Cómo asignar un byte [] para un registro
bien, en este caso, gire a la derecha por 5 posiciones: P –
Su pregunta necesita un poco más de aclaración. Por ejemplo, ¿es una cadena o un número entero real cuyos bits está intentando voltear? El contexto es muy importante al hacer una pregunta. –
@klez - +1 lol, casi me hiciste escupir mi café en mi teclado = P –