- XOR ist eine Operation, die 1 ergibt, wenn sich zwei Bits unterscheiden, und kann als exklusives OR, Ungleichheit, bedingte Invertierung sowie Addition/Subtraktion modulo 2 als ein zusammenhängendes Verhalten verstanden werden
- Bitweises XOR auf Ganzzahlen verarbeitet jede Stelle unabhängig und macht Unterschiede auf Bitebene sichtbar; es verhält sich wie binäre Addition ohne Übertrag und behält Kommutativität, Assoziativität, das neutrale Element 0 und die Eigenschaft des Selbstinversen bei
- In der Kryptografie wird es verwendet, um Klartext mit einem Keystream zu kombinieren; in der früheren Pixelgrafik konnte man dasselbe Bild erneut zeichnen, um es zu löschen und so Speicher- und CPU-Last zu verringern
- Die Eigenschaften von XOR werden direkt in Berechnungen genutzt, die Unterschiede erzeugen und wieder aufheben, etwa bei der Halbaddierer-Identität, beim Bittausch, beim XOR-Swap mit drei Operationen und bei der Gewinnbedingung im Nim-Spiel
- Es setzt sich fort zur symmetrischen Differenz von Mengen, zu Gruppen vom Exponenten 2, zur nim-sum sowie zu linearer Algebra und Polynomen über GF(2) und ist damit auch mit Fehlererkennungs-, Fehlerkorrektur- und Kryptoverfahren wie Hamming-Code, CRC, AES, GCM und Classic McEliece verbunden
Die Grundbedeutung von XOR
- XOR ist eine boolesche Operation mit zwei Eingabebits und einem Ausgabebit; die Wahrheitstabelle lautet
00→0,01→1,10→1,11→0 - Als „exclusive OR“ betrachtet ist das Ergebnis 1, wenn genau eine der beiden Eingaben wahr ist; sind beide wahr, ist das Ergebnis 0
- Als „not equals“ betrachtet ist
a XOR bgleicha ≠ bund liefert 1, wenn sich zwei boolesche Werte unterscheiden - Als bedingte Invertierung betrachtet bleibt
bbeia=0unverändert und wird beia=1umgedreht- Aus demselben Grund kann man auch
bals Steuereingang sehen, derainvertiert
- Aus demselben Grund kann man auch
- Aus Sicht der Parität zeigt XOR an, ob die Anzahl der Einsen in den Eingaben ungerade ist
- Bei zwei Bits ist es gleich
a+b mod 2 - Es ist auch gleich
a-b mod 2 - XORt man mehrere Werte, erkennt man, ob die Gesamtzahl der Einsen in allen Eingaben ungerade oder gerade ist
- Bei zwei Bits ist es gleich
Algebraische Eigenschaften von XOR
- XOR erfüllt Kommutativgesetz und Assoziativgesetz
a XOR b = b XOR a(a XOR b) XOR c = a XOR (b XOR c)- In langen XOR-Listen beeinflussen weder Reihenfolge noch Klammerung das Ergebnis
- 0 ist das neutrale Element von XOR
a XOR 0 = 0 XOR a = a- In langen XOR-Listen kann man 0 entfernen
- Jeder Wert ist sein eigenes Inverses
a XOR a = 0- Tritt dieselbe Variable zweimal auf, können die beiden Terme gemeinsam gestrichen werden
- Man kann auch aus bereits gemischten Werten einen bekannten Term entfernen, indem man ihn noch einmal XORt, etwa bei
(a XOR b) XOR b = a
Bitweises XOR auf Ganzzahlen
- Beim bitweisen XOR von Ganzzahlen werden zwei Ganzzahlen binär betrachtet und die Bits jeder Stelle unabhängig XORt
- Die Eigenschaften von XOR für einzelne Bits gelten unverändert auch für Ganzzahlen
a XOR b = b XOR a(a XOR b) XOR c = a XOR (b XOR c)a XOR 0 = aa XOR a = 0
- Bitweises XOR zeigt Unterschiede auf Bitebene zwischen zwei Ganzzahlen
- Wenn
a=b, dann ista XOR b = 0 - Wenn
a≠b, dann unterscheidet sich mindestens ein Bit und daher ista XOR b ≠ 0 - Die 1-Bits im Ergebnis markieren die Positionen, an denen sich die beiden Eingaben unterscheiden
- Wenn
- Bitweises XOR kann auch als bedingter Bit-Invertierer gesehen werden
- Datenbits werden nur an den Positionen invertiert, an denen der Steuerwert 1-Bits hat
- In ASCII und einigen Nachfolgecodierungen unterscheiden sich lateinische Groß- und Kleinbuchstaben nur in einem Bit; XORt man den Zeichenwert mit 32, kann man zwischen Groß- und Kleinschreibung umschalten
- Diese Regel gilt nicht für alle Unicode-Zeichen; viele Zeichen haben kein Groß-/Kleinschreibungskonzept oder folgen dieser Regel nicht
- Bitweises XOR ist dasselbe wie binäre Addition ohne Übertrag
- An jeder Stelle wird nur modulo 2 addiert, ohne einen Übertrag an die nächste Stelle weiterzugeben
XOR in der Kryptografie
- In der Kryptografie wird ein Keystream mit derselben Länge wie der Klartext erzeugt, und daraus wird ein Chiffretext gebildet, indem Klartext-Bytes oder -Wörter mit dem Keystream kombiniert werden
- Für diesen Kombinationsschritt wird üblicherweise XOR verwendet
- Der Empfänger kann denselben Keystream erneut XORen, um den ursprünglichen Klartext wiederherzustellen
- Es ist zudem etwas praktischer, dass Sender und Empfänger dieselbe Operation verwenden
- Die Erzeugung des Keystreams selbst kann deutlich komplexer sein
- Ein One-Time Pad verwendet echte Zufallsdaten in der vollen Größe der Nachricht und ist unbrechbar, für die meisten Zwecke aber äußerst unpraktisch
- Üblicherweise erzeugen Stromchiffren oder im Counter Mode betriebene Blockchiffren aus einem kleinen Schlüssel einen Keystream der benötigten Länge
- Dieses Verfahren kann bei gutem Keystream Vertraulichkeit bieten, aber keine Integrität, also keinen Schutz gegen Manipulation der Nachricht
- Integritätsschutz ist ein separates Problem
- Das Weglassen der Integrität ist ein häufiger Fehler bei der Entwicklung kryptografischer Systeme für Einsteiger und führt auch bei komplexeren Verschlüsselungsverfahren zu falschen Ergebnissen
- In Hardware ist XOR einfacher als Addition
- Addition benötigt eine Übertragsfortpflanzung zwischen Bits und kostet deshalb mehr Chipfläche und Zeit
- XOR hat keinen Übertrag und ist in spezialisierter Hardware günstiger
XOR-Zeichnen und Pixelgrafik
- Heimcomputer der 1980er Jahre hatten nur wenige Bits pro Bildschirmpixel und wenig RAM, sodass es schwierig war, den gesamten Bildschirm doppelt zu speichern
- Zeichnet man bewegliche Objekte mit XOR, kann man durch erneutes Zeichnen desselben Objekts den ursprünglichen Bildschirm wiederherstellen
- Man XORt den Pixelwert
Sdes Bildschirms mit dem PixelMdes bewegten Objekts und erhältC; später XORt man dasselbeMerneut und gewinntSzurück
- Man XORt den Pixelwert
- Bei Bildschirmen, auf denen mehrere Pixel in einem Byte gepackt sind oder eine Bitplane-Struktur verwendet wird, ist additive Komposition unhandlich
- Bei gewöhnlicher Addition kann ein Übertrag von einem Pixel auf das nächste übergehen
- Bei XOR gibt es überhaupt keinen Übertrag, daher tritt dieses Problem nicht auf
- Zeichnet man Linien mit XOR, können Pixel an Schnittpunkten zweier Linien zweimal invertiert werden und dadurch zur Hintergrundfarbe zurückkehren, was wie ein kleiner Makel aussieht
- Dieser Makel wurde als Preis dafür akzeptiert, dass man eine Linie löschen konnte, ohne andere Linien zu beschädigen
- XOR-Zeichnen war auch für einfache Animationen vorteilhaft
- Man zeichnet eine neue Linie und zeichnet eine alte Linie erneut, um sie zu löschen; so entsteht das nächste Frame
- Es ist nicht nötig, alle Pixel oder alle Linien des aktuellen Bildschirms neu zu zeichnen, was Speicher- und CPU-Nutzung reduziert
- So wurden etwa die bewegten Linien im Spiel Qix von 1981 und auch Fensterumrisse beim Verschieben in frühen GUIs umgesetzt
Halbaddierer-Identität
- Bei der Addition eines Bits ist das niederwertige Bit von
a+bgleicha XOR b, das höherwertige Bit gleicha AND b - Dieselbe Beziehung gilt auch für bitweise Operationen auf Ganzzahlen
a + b = (a XOR b) + 2 × (a AND b)a XOR bist die Summe ohne Übertrag, unda AND benthält die Übertragsbits, die an den jeweiligen Stellen entstanden wären
- Diese Beziehung kann als Halbaddierer-Identität verstanden werden
- Ein Hardware-Halbaddierer erzeugt mit AND- und XOR-Gattern den Übertrag und das niederwertige Bit einer Zwei-Bit-Addition
- Es handelt sich nicht darum, eine vollständige Ganzzahladdition nur mit einfachen Operationen auszudrücken; das
+auf der rechten Seite erledigt weiterhin die Übertragsfortpflanzung
- Diese Identität kann verwendet werden, um den Mittelwert zweier Ganzzahlen ohne Overflow zu berechnen
- Wenn man einfach
a+bbildet und danach nach rechts schiebt, kann das höchstwertige Bit einer 33-Bit-Summe verloren gehen - Auf CPUs ohne Carry-Flag oder mit fehlenden bzw. unpraktischen Befehlen wie RRX/RCR ist die Form
(a XOR b) >> 1 + (a AND b)eine Alternative - Beispiele sind MIPS, RISC-V und DEC Alpha ohne Carry-Flag sowie frühes Arm Thumb ohne RRX
- Wenn man einfach
- Auf CPUs ohne XOR-Befehl kann man die Identität umkehren, um XOR zu erzeugen
a XOR b = (a + b) − 2 × (a AND b)- Data-General-CPUs der 1970er hatten AND, aber kein bitweises XOR
Tausch von Bits und Werten
- Das Problem, zwei Bits zu vertauschen, reduziert sich darauf, dass bei gleichen Bits nichts zu tun ist und bei unterschiedlichen Bits beide Bits invertiert werden müssen
- Mit XOR und Shifts kann man feststellen, ob zwei Bits verschieden sind, und falls nötig beide Positionen invertieren
diff_all = input XOR (input >> distance)berechnet die Unterschiede zwischen Bitpaaren mit festem Abstand- Mit
ANDwerden nur die relevanten Positionen ausgewählt - Die ausgewählten Unterschiede werden auf die andere Position kopiert und dann in den Eingabewert XORt, sodass nur bei Bedarf beide Bits invertiert werden
- Dieselbe Methode kann auch genutzt werden, um mehrere Bitpaare mit demselben Abstand auf einmal zu vertauschen
- Statt einer Ein-Bit-Maske verwendet man dann eine Maske mit mehreren Bits
- Ein Beneš-Netzwerk kann durch das Vertauschen vieler Paare mit gleichem Abstand in mehreren Stufen beliebige Permutationen darstellen
- Auch ein kompletter XOR-Swap mit drei Operationen für zwei Werte ist möglich
a = a XOR bb = b XOR aa = a XOR b- So werden zwei Werte auch ohne temporäre Variable vertauscht
- Der XOR-Swap mit drei Operationen hat ein Aliasing-Problem
- Für zwei verschiedene Variablen funktioniert er
- Wenn aber zwei Namen auf denselben Speicherort zeigen, etwa wenn dasselbe Array-Element mit sich selbst vertauscht wird, kann der Wert zu 0 werden
Das Nim-Spiel und XOR
- Nim ist ein Spiel mit mehreren Haufen, bei dem man abwechselnd einen Haufen auswählt und daraus eine beliebige Anzahl von Spielsteinen, mindestens aber einen, entfernt; wer nicht mehr ziehen kann, verliert
- In der einfachen Variante von Nim sind Verlustpositionen genau die Positionen, bei denen das bitweise XOR aller Haufengrößen 0 ist
- Wenn in einer Position mit XOR 0 eine Haufengröße
ain einen anderen Wertbgeändert wird, ändert sich das gesamte XOR uma XOR b; daa≠b, ist es dann nicht mehr 0 - In einer Position mit XOR ungleich 0 betrachtet man das höchstwertige 1-Bit des gesamten XOR-Werts
x; wählt man einen Haufen, bei dem dieses Bit 1 ist, und reduziert ihn aufpile XOR x, wird das gesamte XOR zu 0 - Im Beispiel haben die Haufen die Größen 12, 10 und 3, also binär
1100,1010,0011; ihr XOR ist0101- Nur der größte Haufen 12 wird durch XOR mit
0101auf 9 reduziert - Der Gewinnzug besteht also darin, aus 12 genau 3 Steine zu entfernen und auf 9 zu gehen
- Nur der größte Haufen 12 wird durch XOR mit
Mathematische Strukturen, die wie XOR aussehen
- In der Mengenlehre ist die symmetrische Differenz
X∆Yeine Operation, die genau die Elemente enthält, die in genau einer der beiden Mengen liegen- Betrachtet man die Zugehörigkeit eines Elements als booleschen Wert, ist die symmetrische Differenz dasselbe wie XOR
- Daher teilt sie XOR-Eigenschaften wie Kommutativität und Assoziativität
- In der Gruppentheorie ist eine Gruppe vom Exponenten 2 eine Gruppe, in der jedes Element sein eigenes Inverses ist
- Eine solche Gruppenoperation ist assoziativ und erfüllt als Standardübung auch Kommutativität
- Dass sich zwei gleiche Elemente gegenseitig aufheben, erinnert an XOR
- Jede Gruppe vom Exponenten 2 kann als bitweises XOR von Funktionen mit
{0,1}-Werten verstanden werden
- In der Sprague-Grundy-Analyse wird vielen impartial games eine Grundy-Zahl zugeordnet
- Die Grundy-Zahl eines Composite aus mehreren Teilspielen ergibt sich als bitweises XOR der Grundy-Zahlen der einzelnen Teilspiele
- In der Spieltheorie wird das bitweise XOR nichtnegativer Ganzzahlen auch nim-sum genannt
- Der Körper
GF(2)ist ein endlicher Körper mit nur den Elementen 0 und 1- Addition und Subtraktion verhalten sich wie XOR
- Multiplikation verhält sich wie AND
- Daher gilt
a AND (b XOR c) = (a AND b) XOR (a AND c)
Lineare Algebra über GF(2) und Fehlerkorrektur
- Vektoren und Matrizen über
GF(2)sind Strukturen, deren Komponenten 0 oder 1 sind; die Addition von Vektoren oder Matrizen ist komponentenweises XOR - Die Multiplikation einer Matrix
Mmit einem Vektorventspricht dem XOR der von den 1-Komponenten invausgewählten Spalten vonM - Fehlerkorrekturcodes erweitern eine
m-Bit-Nachricht zu einem längerenn-Bit-Codewort, sodass einige Bitfehler erkannt oder korrigiert werden können- Wenn sich gültige Codewörter in vielen Bits unterscheiden, wird eine kleine Zahl von Bitfehlern nicht in ein anderes gültiges Codewort verwandelt
- Wenn zwei gültige Codewörter sich in mindestens
kBits unterscheiden, können weniger alskFehler erkannt werden, und weniger alsk/2Fehler können durch Wahl des nächstgelegenen Codeworts korrigiert werden
- Lineare Codes verwenden über
GF(2)eine Generator Matrix und eine Check Matrix- Der Sender erweitert mit der Generator Matrix eine
m-Bit-Nachricht zu einemn-Bit-Codewort - Der Empfänger prüft mit der Check Matrix, ob das empfangene Codewort gültig ist, und erhält bei Fehlern ein Syndrom
- Dasselbe Fehlermuster erzeugt unabhängig von der Nachricht stets dasselbe Syndrom
- Der Sender erweitert mit der Generator Matrix eine
- Der Hamming code ist ein Beispiel für den Fall, dass die Codelänge
ngleich2^d−1ist- Bei
n=15werden die 15 Bitpositionen mit den 4-Bit-Zahlen von 0001 bis 1111 nummeriert, also allen von 0 verschiedenen Zahlen - Der Empfänger XORt die Indizes aller Bits, die 1 sind; ist das Ergebnis 0, liegt ein gültiges Codewort vor
- Wenn ein einzelnes Bit invertiert wurde, ist das XOR-Ergebnis direkt der Index des invertierten Bits, sodass sich ein 1-Bit-Fehler ohne Lookup-Tabelle korrigieren lässt
- Ein 15-Bit-Hamming-Code trägt 11 Datenbits und verwendet 4 Bits für die Fehlerkorrektur
- Bei
Polynome über GF(2), CRC und größere endliche Körper
- Polynome über
GF(2)sind formale Polynome mit Koeffizienten 0 oder 1; Addition entspricht dem XORen der Koeffizienten gleicher Ordnung - Die Multiplikation von Polynomen funktioniert wie bei gewöhnlichen Polynomen, indem Teilprodukte gebildet und die Koeffizienten modulo 2 reduziert werden
- Betrachtet man diese Darstellung als Bitfolge, ähnelt sie der Ganzzahlmultiplikation, nur dass zum Zusammenführen der Teilprodukte statt gewöhnlicher Addition ein carryloses XOR verwendet wird
- x86 bietet Befehle für carrylose Multiplikation einschließlich
CLMUL, und Arm bietet eine Familie von Befehlen für Polynom-Multiplikation
- CRC verwendet den Rest einer Polynomdivision über
GF(2)als Prüfsumme- Die gesendete Bitfolge der Nachricht wird als großes Polynom
Mbetrachtet, und man speichert den RestM mod Pbei Division durch ein vereinbartes PolynomP - Dies wird zur Prüfung von Ethernet- und ähnlichen Netzwerkpaketen verwendet
- CRC korrigiert keine Fehler, sondern erkennt sie nur; das passt zu Situationen, in denen fast alle Übertragungen korrekt sind und nur gelegentlich Bitfehler oder Rauschen auftreten
- Die gesendete Bitfolge der Nachricht wird als großes Polynom
- Größere endliche Körper lassen sich als Restklassenstrukturen von Polynomen über
GF(p)modulo eines irreduziblen PolynomsQbilden- Hat
Qden Gradd, dann besitzt der neue endliche Körperp^dElemente - Für
p=2kann man irreduzible Polynome als Bitmuster wie Ganzzahlen schreiben; diese Folge ist in OEIS A014580 verzeichnet
- Hat
- Endliche Körper mit Größe als Zweierpotenz tauchen in vielen kryptografischen Techniken auf
- Der endliche Körper der Größe
2^8ist ein Kernelement von AES und Twofish - Der endliche Körper der Größe
2^128wird in GCM verwendet, das Bulk Encryption mit Integritätsschutz kombiniert - Endliche Körper mit Größe als Zweierpotenz kommen auch in Teilen der elliptic-curve cryptography und in Dekodierungsalgorithmen des Post-Quantum-Verfahrens Classic McEliece vor
- Der endliche Körper der Größe
1 Kommentare
Hacker-News-Kommentare
Meine liebste verfluchte XOR-Technik ist die XOR-doppelt verkettete Liste: https://en.m.wikipedia.org/wiki/XOR_linked_list
Jeder Knoten speichert nicht getrennt einen Next-/Previous-Pointer, sondern einen einzelnen Wert, der aus dem XOR beider entsteht. Das ist natürlich kein gültiger Pointer, aber beim Traversieren erhält man durch XOR des Previous-Knoten-Pointers mit dem kombinierten Pointer den Next-Knoten-Pointer, und Traversierung in beide Richtungen ist ebenfalls möglich. Fühlt sich irgendwie illegal an
Ein weniger grundlegender Nachteil ist, dass es in strikt standardkonformem C extrem lästig ist, eine XOR-verkettete Liste zu implementieren. Der Standard garantiert nicht, dass beim Casten desselben Pointers zu Integern immer derselbe Integer herauskommt, daher muss man praktisch alles zu
uintptr_tmachen, um eine kanonisierte Integer-Cast-Version beizubehaltenVielleicht sind sogar 16-Bit-Nah-/Relativpointer möglich. Das könnte gut zu Data-Oriented Design passen, etwa mit Blöcken von 64K Elementen, bei denen interne Elemente per
uint16-Index referenziert werdenIch habe noch etwas ausgelassen. XOR ist auch eine 3-wise unabhängige lineare Hashfunktion und kann daher für probabilistische approximativ gleichmäßige Stichprobenziehung von Lösungen boolescher Funktionen sowie zum Zählen verwendet werden. Das ist wirklich nützlich und wird verwendet, um Zähler zu bauen, die probabilistisch sind, aber bewiesene Anzahlen liefern. Eine leichter verständliche Erklärung steht hier: https://www.msoos.org/2018/12/how-approximate-model-counting...
Im Grunde halbiert es den Lösungsraum jedes Mal nahezu exakt. Man fügt also fortlaufend XOR-Bedingungen hinzu, und wenn zum Beispiel noch 10 Lösungen übrig sind und die Anzahl der hinzugefügten XORs k ist, multipliziert man 10 mit 2^k. Weil jedes Mal halbiert wird, erreicht man Größenordnungen von 10 Lösungen schnell, was gut skaliert
Relevante Papers gibt es unter https://arxiv.org/abs/1306.5726 und https://www.cs.toronto.edu/~meel/Papers/cav20-sgm.pdf, die Tools unter https://github.com/meelgroup/approxmc und https://github.com/meelgroup/unigen. Beim letzten Model-Counting-Wettbewerb haben sie in Kombination mit einem exakten Zähler die anderen Teilnehmer klar dominiert; die Folien dazu sind hier: https://mccompetition.org/assets/files/2024/MC2024_awards.pd...
Eine meiner liebsten XOR-Anekdoten stammt von Bryan Cantrill von Oxide, Joyent und Sun, erzählt in dieser Präsentation https://speakerdeck.com/bcantrill/oral-tradition-in-software... und diesem Video https://www.youtube.com/watch?v=4PaWFYm0kEw
Kurz zusammengefasst, damit man die Links nicht anklicken muss: Als er bei Sun war, sprach er mit seinem Kollegen Roger Faulkner darüber, warum C kein logisches XOR hat. Faulkner meinte, das liege daran, dass man dabei keine Kurzschlussauswertung machen könne, und Brian fand das seltsam. Also fragte Roger Dennis Ritchie per E-Mail, und Ritchie bestätigte, dass Faulkner recht hatte. Cantrills Erzählweise ist schon lustig, aber noch erstaunlicher ist, dass man den Beteiligten einfach direkt fragen konnte
dmr@research.att.com, um nach mehr Architekturinformationen zu fragenDamals gab es weder Google noch Material in der Universitätsbibliothek, und ein paar Tage später fragte er nach meiner Postadresse. Einige Wochen danach kam eine Kopie eines Befehlssatz-Kurzreferenzhandbuchs in meinem Briefkasten an. Es wirkte wie aus der IBM-360-Familie, und ich habe es noch immer
!=. Anders als andere logische Operatoren müssen seine Argumente auf einen einzelnen Wahrheitswert normalisiert werden, und er passt gut zum Bool-Konvertierungsidiom!!in C^: https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/Ich habe heute gelernt, dass das XORen des Auto-Emojis mit
0x20, also gewissermaßen dessen „Kleinschreibung“, zum Fußgänger-verboten-Emoji wird. Das passt ein bisschen zu perfekt für einen Zufall, deshalb frage ich mich, ob das absichtlich so gemacht wurde und ob das jemand weißWenn man das zu weit treibt, könnte man auf den seltsamen Gedanken kommen, dass die Kleinschreibung des Auto-Emojis ein Schild für „Fußgänger verboten“ ist
>>> from unicodedata import lookup, name>>> name(chr(ord(lookup('AUTOMOBILE')) ^ 0x20))'NO PEDESTRIANS':tada:→:tophat:,:rocket:→:mountain_cableway:geht auchEine gute Alltagsmetapher, um XOR zu erklären, ist ein Lichtschalter an einer Treppe. Unten gibt es einen Schalter, oben einen zweiten, und beide steuern dasselbe Licht
Anfangs stehen beide auf Aus; wenn man den unteren Schalter einschaltet, geht das Licht an. Geht man die Treppe hoch und schaltet den oberen Schalter ein, stehen beide Schalter auf „Ein“, aber das Licht ist aus. Das Licht ist nur dann an, wenn genau ein Schalter auf „Ein“ und der andere auf „Aus“ steht; sonst ist es aus
Ich mag es überhaupt nicht, dass für diese logische Funktion so oft der Name XOR, also „exklusives ODER“, verwendet wird. Fast immer ist eigentlich „Summe modulo 2“, also Parität, gemeint und nicht exklusives ODER
„Summe modulo 2“/Parität und „exklusives ODER“ sind unterschiedliche logische Funktionen und stimmen nur zufällig überein, wenn es genau 2 Eingabeoperanden gibt. Das liegt daran, dass es unter 2 nur eine ungerade Zahl gibt
Bei 3 oder mehr Eingängen ist das, was die meisten XOR nennen, in Wirklichkeit Parität: also 1 genau dann, wenn eine ungerade Anzahl von Eingängen 1 ist. Exklusives ODER ist dagegen bei 3 oder mehr Eingängen die Funktion, die nur dann 1 ergibt, wenn genau ein Eingang 1 und alle übrigen 0 sind
In Computerhardware ist Parität viel wichtiger als exklusives ODER. Der Hauptgrund ist, dass Addition modulo 2 als Baustein zur Implementierung der Addition größerer Zahlen dient. In der Mathematik hingegen ist exklusives ODER viel wichtiger als Parität
Zum Beispiel basieren Quantoren, die ausdrücken, dass ein Prädikat für einige Elemente einer Menge, für alle Elemente oder für genau ein Element wahr ist, jeweils auf ODER, UND und exklusivem ODER. Das „or“ in natürlicher Sprache bedeutet immer inklusives ODER oder exklusives ODER, aber nie die Parität, die viele Programmierer XOR nennen
In der Programmierung muss man die logische Funktion exklusives ODER selten tatsächlich berechnen, aber zur Beschreibung des Programmverhaltens wird sie oft verwendet. Etwa wenn man sagt, dass in einer select/case/switch-Verbundanweisung der erste oder der zweite oder der dritte Zweig ausgeführt wird, oder wenn man die möglichen Typen des aktuellen Werts einer Union-/Sum-Typ-Variablen beschreibt
=1, ein Paritätsgatter mit2k + 1gekennzeichnet. Wer aber Schaltungsentwurfssoftware für PCBs oder FPGAs verwendet, kann trotzdem noch etwas anderes bekommen als erwartet∃!Es gibt auch die verteilte Kademlia-Hash-Tabelle: kademlia distributed hash table. Die große Idee ist, dass jeder Knoten zufällige Bits aus dem Bereich
[0, 2^m)erhält und die Distanz per XOR definiert wird. Gesucht ist ein verteilter Algorithmus, mit dem man Informationen schnell von X nach Y schicken kann, ohne das gesamte Netzwerk zu kennenMan kann allein mit Mathematik beweisen, dass das funktioniert, aber meine liebste visuelle Intuition ist diese: Angenommen, der Startknoten X möchte den Knoten k finden. Definiere den „X-Distanzbaum“ als Binärbaum, dessen Blattindizes 0, 1, 2 ... sind, und versieh jedes Blatt mit dem Label
X^leaf_index, sodass es die Distanz zu X darstellt. Weil zum Beispieldist(x, x) = x^x = 0gilt, landet das Label des ursprünglichen Knotens X auf dem ganz linken Blatt 0Das Intervall
[2^i, 2^(i+1))ist ein bestimmter Teilbaum des X-Distanzbaums. Wenn man weiß, dass die Distanz zu k in dieses Intervall fällt, fragt man irgendeinen Knoten Y darin als ungefähren Nachbarn anGanz gleich, welches Y man wählt: Im Y-Distanzbaum ist das resultierende Präfix immer eine Permutation des gewählten Teilbaums
[2^i, 2^(i+1))aus dem X-Distanzbaum. Genauer kann man es alslabels_of_leaves_of_X([2^i, 2^(i+1))) == labels_of_leaves_of_Y([0, 2^i))auffassen. Die Indizes beziehen sich auf die Distanz, aber die Labels können unterschiedlich seinFür Vergleiche mit anderen verteilten Hash-Tabellen wie Chord gibt es mathematisch und empirisch deutlich rigoroseres Material. Aber diese visuelle Intuition vermittelt ein Gefühl dafür, was die „Symmetrie“ von Kademlia ist: Jeder hat seine eigenen lokalen Nachbarn und seinen eigenen Teilbaum
Chord dagegen scheint, selbst wenn es bidirektional implementiert wird, doppelt so viel Speicher zu brauchen und riskanter in der Implementierung zu sein, und es ist schwer, ein solches Maß an „Isolierung“ zu erreichen. Das gleitende Nachbarfenster der Größe S ist ständig in Bewegung, und pro Bit gibt es
2^munterschiedliche Nachbarn. Auch wenn viele Nachbarn ähnlich aussehen, ist das nicht besonders elegantKademlia hat
1 + 2 + 4 ... + 2^m-1Nachbarn, und das Ganze ist ordentlich strukturiertFalls sich das jemand fragt: Das ist Simon Tatham aus Simon Tatham's Portable Puzzle Collection. Wenn ihr das nicht kennt, ist das eine gute Beschäftigung für langweilige Offline-Momente
Ich habe in der Oberstufe viel zu viel Zeit damit verbrannt: https://www.chiark.greenend.org.uk/~sgtatham/puzzles/
Heutzutage werden viele spezialisierte Optimierungs-Solver, zum Beispiel Ising Machines, mit dem XOR-Problem benchmarked. Tatsächlich ist das Lösen mehrerer XOR-Klauseln per Gauß-Elimination in polynomialer Zeit möglich, daher ist der praktische Nutzen etwas begrenzt, aber da die Solver alle exponentielle Skalierung zeigen, ist es dennoch eine gute Methode, ihre Leistung einzuschätzen.
Eine zweite interessante Implementierung hängt mit dem McEliece-Kryptosystem zusammen. Es handelt sich um ein Public-Key-Kryptosystem aus den 70er-Jahren, das heute wegen seiner Quantenresistenz wieder Aufmerksamkeit erhält. Ein Entschlüsselungsangriff ist das Problem, eine Lösung für ein System von XOR-Gleichungen zu finden; auch das ist in polynomialer Zeit lösbar, allerdings unter der zusätzlichen Bedingung, dass die Hamming-Distanz einem bestimmten Wert entspricht, der im öffentlichen Schlüssel enthalten ist.
Als ich für die Programmierung des TI-83 Z80-Assembly lernte, zählte jedes einzelne Byte Maschinencode. Der gesamte Speicher des Taschenrechners betrug nämlich nur 24 KB.
Um das Hauptakkumulator-Register
aauf 0 zu initialisieren, verwendete manXOR astattLD a, 0. Bei Rechenbefehlen istader implizite Operand, daher XORtXOR aamit sich selbst, und der gesamte Befehl ist nur 1 Byte lang. Wenn man dagegen 0 explizit inaladen will, muss das Literal 0 im Opcode enthalten sein, daher istLD a, 0ein 2-Byte-Befehl.