XOR
(chiark.greenend.org.uk)- XOR es una operación que da 1 cuando dos bits son distintos entre sí, y puede entenderse conectando en una sola idea el OR exclusivo, la desigualdad, la inversión condicional y la suma/resta módulo 2
- El XOR bit a bit sobre enteros procesa cada posición de forma independiente y revela la diferencia por bit, funcionando como una suma binaria sin acarreo mientras conserva las propiedades conmutativa, asociativa, el elemento identidad 0 y el inverso de sí mismo
- En criptografía se usa para combinar texto plano con un keystream, y en los gráficos por píxeles del pasado permitía borrar redibujando la misma figura, reduciendo la carga de memoria y CPU
- Las propiedades de XOR se aprovechan directamente en cálculos que crean diferencias y luego las cancelan, como la identidad del half adder, el intercambio de bits, el swap con tres XOR y la condición ganadora del juego Nim
- Se extiende a la diferencia simétrica de conjuntos, los grupos de exponente 2, el nim-sum y hasta el álgebra lineal y los polinomios sobre GF(2), conectándose también con técnicas de detección/corrección de errores y criptografía como Hamming code, CRC, AES, GCM y Classic McEliece
Significado básico de XOR
- XOR es una operación booleana con dos bits de entrada y un bit de salida, y su tabla de verdad es
00→0,01→1,10→1,11→0 - Visto como “exclusive OR”, da 1 cuando solo una de las dos entradas es verdadera, y 0 cuando ambas lo son
- Visto como “not equals”,
a XOR bes igual aa ≠ b, así que produce 1 cuando los dos valores booleanos son distintos - Visto como inversión condicional, cuando
a=0dejabtal como está, y cuandoa=1invierteb- Por la misma razón, también puede interpretarse viendo
bcomo entrada de control e invirtiendoa
- Por la misma razón, también puede interpretarse viendo
- Desde la perspectiva de la paridad, indica si la cantidad de unos en la entrada es impar
- Con dos bits, es igual a
a+b mod 2 - También es igual a
a-b mod 2 - Si se hace XOR de varios valores, se puede saber si la cantidad total de unos en la entrada es impar o par
- Con dos bits, es igual a
Propiedades algebraicas de XOR
- XOR satisface las propiedades conmutativa y asociativa
a XOR b = b XOR a(a XOR b) XOR c = a XOR (b XOR c)- En una lista larga de XOR, ni el orden ni la forma de agrupar cambian el resultado
- 0 es el elemento identidad de XOR
a XOR 0 = 0 XOR a = a- En una lista larga de XOR, se pueden eliminar los 0
- Todo valor es su propio inverso
a XOR a = 0- Si la misma variable aparece dos veces, ambos términos pueden eliminarse juntos
- En un valor ya mezclado, como
(a XOR b) XOR b = a, se puede eliminar un término conocido aplicando XOR una vez más
XOR bit a bit sobre enteros
- El XOR bit a bit de enteros toma dos enteros en binario y aplica XOR de forma independiente a cada posición
- Las propiedades del XOR de un solo bit se aplican igual a los enteros
a XOR b = b XOR a(a XOR b) XOR c = a XOR (b XOR c)a XOR 0 = aa XOR a = 0
- El XOR bit a bit muestra la diferencia por bit entre dos enteros
- Si
a=b, entoncesa XOR b = 0 - Si
a≠b, al menos un bit difiere, así quea XOR b ≠ 0 - Los bits en 1 del resultado indican las posiciones en que las dos entradas son distintas
- Si
- El XOR bit a bit también puede verse como un inversor condicional de bits
- Solo invierte los bits de datos en las posiciones donde el valor de control tiene bits en 1
- En ASCII y algunas codificaciones derivadas, las letras latinas mayúsculas y minúsculas difieren en un solo bit, por lo que hacer XOR con 32 sobre el valor del carácter puede cambiar entre mayúsculas y minúsculas
- Esta regla no se aplica a todos los caracteres Unicode, y muchos no tienen distinción entre mayúsculas y minúsculas o no siguen esa regla
- El XOR bit a bit es equivalente a una suma binaria sin acarreo
- En cada posición solo se hace una suma módulo 2, sin propagar acarreo a la posición siguiente
XOR en criptografía
- En criptografía, se usa un método que genera un keystream del mismo largo que el texto plano, y produce el texto cifrado combinando los bytes o palabras del texto plano con ese keystream
- En esa etapa de combinación se usa normalmente XOR
- El receptor puede recuperar el texto plano original aplicando XOR otra vez con el mismo keystream
- También resulta un poco más conveniente que emisor y receptor usen la misma operación
- La forma de generar el keystream puede ser más compleja
- El one-time pad usa datos verdaderamente aleatorios del tamaño completo del mensaje y es irrompible, pero para la mayoría de los fines es muy poco práctico
- Lo habitual es que un cifrador de flujo o un cifrador de bloque operando en counter mode genere un keystream del largo necesario a partir de una clave pequeña
- Este método puede proporcionar confidencialidad cuando el keystream es bueno, pero no proporciona integridad para detectar manipulación del mensaje
- La protección de integridad es un problema aparte
- Omitir la integridad es un error común en el diseño de sistemas criptográficos principiantes, y también causa resultados incorrectos en esquemas más complejos
- En hardware, XOR es más simple que la suma
- La suma necesita propagar el acarreo entre bits, lo que consume más espacio en el chip y más tiempo
- Como XOR no tiene acarreo, es más barato en circuitos dedicados
Dibujo con XOR y gráficos por píxeles
- En las computadoras domésticas de los años 1980, la cantidad de bits por píxel y la RAM eran limitadas, por lo que era difícil guardar dos copias completas de la pantalla
- Si un objeto en movimiento se dibuja con XOR, basta con dibujar el mismo objeto otra vez para restaurar la pantalla original
- Se hace XOR entre el valor del píxel
Sy el píxelMdel objeto móvil para obtenerC, y luego se vuelve a aplicar XOR con el mismoMpara recuperarS
- Se hace XOR entre el valor del píxel
- En pantallas donde varios píxeles van packed dentro de un byte o se usa una estructura de bit planes, la composición basada en suma se vuelve complicada
- La suma normal puede hacer que el acarreo de un píxel pase al siguiente
- XOR no tiene ningún acarreo, así que evita ese problema
- Si se dibujan líneas con XOR, los píxeles donde se cruzan dos líneas se invierten dos veces y vuelven al color de fondo, por lo que pueden verse como una pequeña imperfección
- Esa imperfección se aceptaba a cambio de poder borrar una línea sin dañar la otra
- El dibujo con XOR también favorecía las animaciones simples
- Dibujar una línea nueva y volver a dibujar una línea vieja para borrarla producía el siguiente cuadro
- No era necesario redibujar todos los píxeles ni todas las líneas de la pantalla actual, así que el uso de memoria y CPU era bajo
- Este método se usó en la línea móvil del juego Qix de 1981 y en los contornos de movimiento de ventanas en interfaces gráficas tempranas
Identidad del half adder
- En la suma de un bit, el bit bajo de
a+besa XOR by el bit alto esa AND b - La misma relación también vale para las operaciones bit a bit sobre enteros
a + b = (a XOR b) + 2 × (a AND b)a XOR bes el valor sumado sin acarreo, ya AND bcontiene los bits de acarreo que debían producirse en cada posición
- Esta relación puede verse como la identidad del half adder
- Un half adder de hardware usa compuertas AND y XOR para generar el acarreo y el bit bajo de una suma de dos bits
- No significa que la suma completa de enteros se construya solo con operaciones simples; el
+del lado derecho es el que termina la propagación de acarreos
- Esta identidad puede usarse para calcular el promedio de dos enteros sin overflow
- Si simplemente se hace
a+by luego un shift a la derecha, se puede perder el bit más alto de una suma de 33 bits - En CPUs donde no existe o no resulta conveniente una carry flag o instrucciones como RRX/RCR, una forma como
(a XOR b) >> 1 + (a AND b)puede ser una alternativa - Ejemplos: MIPS, RISC-V y DEC Alpha no tienen carry flag, y Arm Thumb temprano no incluía RRX
- Si simplemente se hace
- En CPUs sin instrucción XOR, esta identidad puede invertirse para construir XOR
a XOR b = (a + b) − 2 × (a AND b)- Las CPUs de Data General de los años 1970 tenían AND, pero no XOR bit a bit
Intercambio de bits y valores
- El problema de intercambiar dos bits se reduce a que, si los dos bits son iguales, no hay que hacer nada, y si son distintos, basta con invertir ambos bits
- Con XOR y shifts se puede detectar si dos bits difieren y, si hace falta, invertir ambas posiciones
diff_all = input XOR (input >> distance)calcula la diferencia entre pares de bits separados por una distancia fija- Con
ANDse seleccionan solo las posiciones de interés - Luego esa diferencia seleccionada se replica en la otra posición y se aplica XOR sobre la entrada para invertir ambas solo cuando haga falta
- El mismo método también puede usarse para intercambiar al mismo tiempo varios pares de bits separados por la misma distancia
- En vez de una máscara de un solo bit, se usa una máscara con varios bits
- Una Beneš network puede representar una permutación arbitraria intercambiando muchos pares a la misma distancia a lo largo de varias etapas
- También es posible hacer el swap con tres XOR de dos valores completos
a = a XOR bb = b XOR aa = a XOR b- Así, los dos valores quedan intercambiados sin usar una variable temporal
- El swap con tres XOR tiene un problema de aliasing
- Funciona cuando se intercambian variables distintas
- Si dos nombres apuntan a la misma ubicación de memoria, como al intercambiar un elemento de un arreglo consigo mismo, el valor puede convertirse en 0
El juego Nim y XOR
- Nim es un juego en el que, por turnos, se elige un montón entre varios y se retiran una o más fichas, en la cantidad que se quiera, y pierde quien ya no puede mover
- En la versión simple de Nim, una posición perdedora es aquella donde el XOR bit a bit de los tamaños de todos los montones da 0
- Si en una posición con XOR 0 se cambia el tamaño de un montón de
aa otro valorb, el XOR total cambia ena XOR b, y comoa≠b, deja de ser 0 - En una posición donde el XOR no es 0, se observa el bit más alto en 1 del valor total
x, y si se elige un montón que tenga ese bit en 1 y se reduce su tamaño apile XOR x, el XOR total puede llevarse a 0 - Por ejemplo, los tamaños 12, 10 y 3 en binario son
1100,1010y0011, y su XOR es0101- Solo el montón grande 12 se reduce a 9 al aplicarle XOR con
0101 - La jugada ganadora consiste en quitar 3 fichas del 12 para dejarlo en 9
- Solo el montón grande 12 se reduce a 9 al aplicarle XOR con
Estructuras matemáticas que se parecen a XOR
- En teoría de conjuntos, la diferencia simétrica
X∆Yes la operación que incluye un elemento cuando pertenece exactamente a uno de los dos conjuntos- Si la pertenencia de un elemento se ve como un valor booleano, la diferencia simétrica es igual a XOR
- Por eso comparte propiedades de XOR como la conmutatividad y la asociatividad
- En teoría de grupos, un grupo de exponente 2 es un grupo en el que todo elemento es su propio inverso
- La operación de estos grupos satisface la asociatividad y, como ejercicio estándar, también se deduce la conmutatividad
- El hecho de que dos elementos iguales juntos se cancelen recuerda a XOR
- Todo grupo de exponente 2 puede entenderse como una forma de XOR bit a bit sobre ciertas funciones con valores en
{0,1}
- En el análisis de Sprague-Grundy, a muchas posiciones de impartial game se les asigna un número de Grundy
- El número de Grundy de un composite formado por varios subjuegos se calcula haciendo XOR bit a bit de los números de Grundy de cada juego componente
- En teoría de juegos, al XOR bit a bit de enteros no negativos también se le llama nim-sum
- El cuerpo
GF(2)es un cuerpo finito con solo los elementos 0 y 1- La suma y la resta funcionan como XOR
- La multiplicación funciona como AND
- Por eso se cumple
a AND (b XOR c) = (a AND b) XOR (a AND c)
Álgebra lineal sobre GF(2) y corrección de errores
- Los vectores y matrices sobre
GF(2)son estructuras cuyas componentes son 0 o 1, y la suma de vectores o matrices es XOR componente por componente - Multiplicar una matriz
Mpor un vectorvequivale a combinar con XOR las columnas deMseleccionadas por las componentes en 1 dev - Los códigos de corrección de errores expanden un mensaje de
mbits en una palabra de código más larga denbits para poder detectar o corregir algunos errores de bits- Si las palabras de código válidas difieren entre sí en muchos bits, una pequeña cantidad de errores no las convierte en otra palabra válida distinta
- Si dos palabras válidas difieren al menos en
kbits, menos dekerrores pueden detectarse, y menos dek/2errores pueden corregirse buscando la palabra válida más cercana
- Los códigos lineales usan una generator matrix y una check matrix sobre
GF(2)- El sender expande el mensaje de
mbits a una palabra de código denbits usando la generator matrix - El receiver verifica con la check matrix si la palabra recibida es válida y, si hay error, obtiene un syndrome
- El mismo patrón de error genera el mismo syndrome sin importar el mensaje
- El sender expande el mensaje de
- El Hamming code es un ejemplo cuando la longitud del código
nes2^d−1- Si
n=15, las posiciones de los 15 bits se numeran con números binarios no cero de 4 bits, de 0001 a 1111 - El receptor hace XOR de todos los índices de los bits en 1, y si el resultado es 0, la palabra de código es válida
- Si un bit se invierte, el resultado del XOR pasa a ser exactamente el índice del bit invertido, lo que permite corregir un error de 1 bit sin tabla de búsqueda
- El Hamming code de 15 bits almacena 11 bits de datos y usa 4 bits para corrección de errores
- Si
Polinomios sobre GF(2), CRC y cuerpos finitos más grandes
- Los polinomios sobre
GF(2)son polinomios formales cuyos coeficientes son 0 o 1, y sumarlos equivale a hacer XOR entre coeficientes del mismo grado - La multiplicación de polinomios se hace como en los polinomios normales, formando productos parciales y reduciendo los coeficientes módulo 2
- Si esta representación se ve como una secuencia de bits, se parece a la multiplicación de enteros, pero al combinar los productos parciales se usa XOR sin acarreo en lugar de suma normal
- x86 ofrece instrucciones de multiplicación sin acarreo, incluido
CLMUL, y Arm ofrece instrucciones de la familia de multiplicación polinomial
- El CRC usa como checksum el residuo de una división de polinomios sobre
GF(2)- La secuencia de bits del mensaje enviado se ve como un gran polinomio
M, y se conserva el residuoM mod Pal dividirlo por un polinomio acordadoP - Se usa para verificar paquetes de red como los de Ethernet y tecnologías similares
- El CRC no corrige errores, solo los detecta, y está pensado para situaciones donde casi todas las transmisiones son correctas y solo ocasionalmente aparecen bits volteados o ruido
- La secuencia de bits del mensaje enviado se ve como un gran polinomio
- Los cuerpos finitos más grandes pueden construirse como la estructura de residuos al dividir polinomios sobre
GF(p)por un irreducible polynomialQ- Si el grado de
Qesd, el nuevo cuerpo finito tienep^delementos - Cuando
p=2, el irreducible polynomial puede escribirse como un patrón de bits parecido a un entero, y esa secuencia aparece en OEIS A014580
- Si el grado de
- Los cuerpos finitos de tamaño potencia de 2 aparecen en varias técnicas criptográficas
- El cuerpo finito de tamaño
2^8es un componente central de AES y Twofish - El cuerpo finito de tamaño
2^128se usa en GCM, que combina bulk encryption con protección de integridad - Los cuerpos finitos de tamaño potencia de 2 también aparecen en algunas formas de elliptic-curve cryptography y en el algoritmo de decodificación del esquema post-cuántico Classic McEliece
- El cuerpo finito de tamaño
1 comentarios
Opiniones de Hacker News
Mi técnica maldita favorita con XOR es la lista doblemente enlazada XOR: https://en.m.wikipedia.org/wiki/XOR_linked_list
En vez de que cada nodo guarde por separado los punteros al siguiente/anterior, guarda un único valor que es el XOR de ambos. Obviamente es un puntero no válido, pero al recorrer la lista, si haces XOR entre el puntero al nodo anterior y el puntero combinado, obtienes el puntero al siguiente nodo, y también se puede recorrer en ambos sentidos. Se siente como algo ilegal.
Un defecto menos esencial es que escribir una lista enlazada XOR en C estrictamente conforme al estándar es muy molesto. El estándar no garantiza que, al castear el mismo puntero a un entero, se obtenga el mismo entero, así que en la práctica hay que hacer que todo sea
uintptr_tpara mantener una versión normalizada casteada a entero.Yendo más allá, quizá también sean posibles punteros cercanos/relativos de 16 bits. Podría encajar bien con el diseño orientado a datos: por ejemplo, tener bloques de 64K elementos y apuntar a los elementos internos con índices
uint16.Falta algo. XOR también es una función hash lineal 3-wise independiente, así que se puede usar para muestreo casi uniforme probabilístico de soluciones de funciones booleanas y para conteo. Es realmente útil, y se usa para crear contadores que dan conteos probabilísticos pero demostrados. Dejé una explicación más fácil de entender aquí: https://www.msoos.org/2018/12/how-approximate-model-counting...
Básicamente, cada vez reduce el espacio de soluciones casi exactamente a la mitad. Entonces se siguen agregando condiciones XOR hasta que, por ejemplo, quedan 10 soluciones; si la cantidad de XOR agregados es k, basta con multiplicar 10 por 2^k. Como se reduce a la mitad en cada paso, se llega rápido incluso al orden de 10 soluciones, por lo que escala bien.
Los artículos relacionados están en https://arxiv.org/abs/1306.5726 y https://www.cs.toronto.edu/~meel/Papers/cav20-sgm.pdf, y las herramientas están en https://github.com/meelgroup/approxmc y https://github.com/meelgroup/unigen. En la última competencia de conteo de modelos, al combinarlo con un contador exacto, aplastó a los demás competidores; las diapositivas están en https://mccompetition.org/assets/files/2024/MC2024_awards.pd....
Una de mis anécdotas favoritas sobre XOR es la que contó Bryan Cantrill, de Oxide, Joyent y Sun, en esta presentación https://speakerdeck.com/bcantrill/oral-tradition-in-software... y en este video https://www.youtube.com/watch?v=4PaWFYm0kEw
Para resumir sin que tengan que abrir el enlace: cuando estaba en Sun, hablaba con su colega Roger Faulkner sobre por qué C no tiene un XOR lógico; Faulkner dijo que era porque no podía tener evaluación de cortocircuito, y a Brian eso le pareció raro. Entonces Roger le preguntó por email a Dennis Ritchie, y Ritchie confirmó que Faulkner tenía razón. La forma en que Cantrill lo cuenta también es graciosa, pero lo sorprendente es que pudieran preguntarle directamente a la persona involucrada.
dmr@research.att.compreguntando si había más información de arquitectura.En esa época no había Google y tampoco había material en la biblioteca de la universidad; unos días después me pidió mi dirección física, y unas semanas más tarde llegó a mi buzón una copia de un manual resumido del conjunto de instrucciones. Tenía aire a la familia IBM 360, y todavía lo conservo.
!=. A diferencia de otros operadores lógicos, hay que normalizar sus argumentos a un único valor verdadero, y encaja bien con el modismo de conversión booleana de C,!!.^durante más de 40 años: https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/Hoy me enteré de que si haces XOR del emoji de auto con
0x20, es decir, si lo “pasas a minúsculas”, se convierte en el emoji de prohibido el paso a peatones. Parece una coincidencia demasiado perfecta, así que me pregunto si alguien sabe si fue intencional.Si uno lleva la idea demasiado lejos, hasta se puede pensar algo raro como que la minúscula del emoji de auto es la señal de “prohibido peatones”.
>>> from unicodedata import lookup, name>>> name(chr(ord(lookup('AUTOMOBILE')) ^ 0x20))'NO PEDESTRIANS':tada:→:tophat:,:rocket:→:mountain_cableway:.Una buena analogía del mundo real para explicar XOR es el interruptor de luz de una escalera en casa. Hay un interruptor abajo y otro arriba, y ambos controlan la misma luz.
Al principio los dos están en posición de apagado; si enciendes el interruptor de abajo, la luz se prende. Subes la escalera y enciendes el interruptor de arriba, y aunque ambos interruptores están en posición de “encendido”, la luz se apaga. La luz solo está prendida cuando un interruptor está en “encendido” y el otro en “apagado”; en los demás casos está apagada.
Realmente no me gusta que a esta función lógica se le llame comúnmente XOR, es decir, “OR exclusivo”. Casi siempre lo que en realidad significa es “suma módulo 2”, o sea paridad, no OR exclusivo.
“Suma módulo 2”/paridad y “OR exclusivo” son funciones lógicas distintas, y solo coinciden por casualidad cuando hay 2 operandos de entrada. Esto se debe a que hay un solo número impar menor o igual que 2.
Cuando hay 3 o más entradas, lo que la mayoría llama XOR en realidad es paridad: una función que vale 1 cuando una cantidad impar de entradas vale 1. En cambio, el OR exclusivo con 3 o más entradas es una función que solo vale 1 cuando exactamente una entrada vale 1 y todas las demás valen 0.
En hardware de computadoras, la paridad es mucho más importante que el OR exclusivo. La razón principal es que la suma módulo 2 se usa como bloque de construcción para implementar la suma de números más grandes. En cambio, en matemáticas el OR exclusivo es mucho más importante que la paridad.
Por ejemplo, los cuantificadores que expresan que un predicado es verdadero para algunos elementos, para todos los elementos o para un único elemento de un conjunto se basan respectivamente en OR, AND y OR exclusivo. El “or” del lenguaje natural siempre significa OR inclusivo u OR exclusivo, no la paridad que muchos programadores llaman XOR.
En programación es raro tener que calcular la función lógica de OR exclusivo, pero se usa con frecuencia para describir el comportamiento de un programa. Por ejemplo, cuando se dice que en una construcción select/case/switch se ejecuta una de la primera, la segunda o la tercera sentencia, o al describir los tipos que puede tener el valor actual de una variable de unión/tipo suma.
=1, y una compuerta de paridad como2k + 1. Pero al usar software de diseño de circuitos para PCB o FPGA, todavía puedes terminar recibiendo algo distinto de lo que esperabas.∃!.También está la tabla hash distribuida Kademlia: kademlia distributed hash table. La gran idea es que cada nodo recibe bits aleatorios en el rango
[0, 2^m), y la distancia se define con XOR. Se busca un algoritmo distribuido que permita enviar información rápidamente de X a Y sin conocer toda la red.Se puede demostrar que funciona solo con las matemáticas, pero mi intuición visual favorita es esta. Supongamos que el nodo inicial X quiere encontrar el nodo k. Definimos el “árbol de distancias desde X” como un árbol binario cuyos índices de hoja son 0, 1, 2..., y a cada hoja le ponemos una etiqueta
X^leaf_indexpara indicar su distancia respecto de X. Por ejemplo, comodist(x, x) = x^x = 0, la etiqueta del nodo original X queda en la hoja 0, la de más a la izquierda.El intervalo
[2^i, 2^(i+1))es algún subárbol del árbol de distancias desde X. Si sabemos que la distancia de k cae dentro de ese intervalo, consultamos como vecino aproximado a algún nodo Y dentro de él.Elijas el Y que elijas, en el árbol de distancias desde Y el prefijo resultante siempre será alguna permutación del subárbol
[2^i, 2^(i+1))elegido en el árbol de distancias desde X. Más precisamente, puede verse comolabels_of_leaves_of_X([2^i, 2^(i+1))) == labels_of_leaves_of_Y([0, 2^i)). Los índices se basan en la distancia, aunque las etiquetas pueden cambiar.Hay mucho material bastante más riguroso, tanto matemático como empírico, que compara esto con otras tablas hash distribuidas como Chord. Pero esta intuición visual da una idea de qué es la “simetría” de Kademlia: todos tienen sus propios vecinos locales y su propio subárbol.
En cambio, Chord, aunque se implemente en ambas direcciones, usa el doble de memoria, parece más riesgoso de implementar y es difícil obtener este nivel de “aislamiento”. Una ventana deslizante de vecinos de tamaño S siempre se está moviendo, y por cada bit existen
2^mvecinos distintos. Aunque la mayoría de los vecinos se parezcan, no queda tan limpio.Kademlia tiene
1 + 2 + 4 ... + 2^m-1vecinos, y todo queda ordenado.Para quien tenga curiosidad, esta persona es el Simon Tatham de Simon Tatham's Portable Puzzle Collection. Si no la conoces, vale la pena probarla cuando estés aburrido sin conexión.
En la secundaria gasté muchísimo tiempo con estos juegos: https://www.chiark.greenend.org.uk/~sgtatham/puzzles/
Hoy en día, muchos solucionadores de optimización personalizados, por ejemplo Ising Machine, usan el problema XOR como benchmark. En realidad, resolver varias cláusulas XOR es posible en tiempo polinómico mediante eliminación gaussiana, así que su utilidad es algo limitada, pero como todos los solucionadores muestran escalamiento exponencial, sí sirve como una buena forma de estimar el rendimiento.
La segunda implementación interesante está relacionada con el criptosistema McEliece. Es un sistema de criptografía de clave pública de los años 70, y últimamente vuelve a llamar la atención por su resistencia cuántica. Un ataque de descifrado consiste en encontrar una solución a un conjunto de ecuaciones XOR; también es de tiempo polinómico, pero con la condición adicional de que la distancia de Hamming debe ser igual a cierto número incluido en la clave pública.
Cuando aprendía ensamblador Z80 para programar la TI-83, cada byte de código máquina importaba. Eso era porque el almacenamiento total de la calculadora era de apenas 24 KB.
Para inicializar en 0 el registro acumulador principal
a, se usabaXOR aen vez deLD a, 0. En las instrucciones matemáticas,aes el operando automático, así queXOR ahace XOR deaconsigo mismo, y la instrucción completa ocupa solo 1 byte. En cambio, para cargar explícitamente 0 ena, el literal 0 tiene que estar incluido en el opcode, por lo queLD a, 0es una instrucción de 2 bytes.