Bitsgewijze bewerkingen in de praktijk: AND, OR, XOR, shifts, maskers
Je opent een legacy PostgreSQL-migratie en ziet permissions & 0b100. Een collega levert een feature-flag-systeem dat 32 booleans in één integer pakt. Een Kubernetes subnet-calculator spuugt 192.168.1.0/24 uit en je moet het netwerkadres in code achterhalen. Drie situaties, één onderliggende vaardigheid: bitsgewijze bewerkingen.
De meeste applicatielaag-ontwikkelaars hoeven nooit naar & of ^ in een webapplicatie te grijpen — totdat het ineens wel moet. Deze gids behandelt de zes bitwise-operatoren, tweescomplement, negen patronen die het onthouden waard zijn, en de taalspecifieke valkuilen die je bijten (vooral in JavaScript). Code staat in JS, Python, Go en C, en elk voorbeeld is uitvoerbaar.
Open onze Talstelsel-omrekenen in een ander tabblad. Meerdere secties nodigen je uit een getal in te typen en te kijken hoe het bitpatroon verandert.
Waarom bitsgewijze bewerkingen in 2026 nog steeds belangrijk zijn
Hogere programmeertalen hebben bitsgewijze bewerkingen niet overbodig gemaakt. Ze hebben alleen verborgen waar die bewerkingen plaatsvinden. Een paar plaatsen waarop je er vandaag al op rekent, of je het beseft of niet:
- PostgreSQL row-level security gebruikt een bitmap van ACL-rechten (
SELECT,INSERT,UPDATE,DELETE, …) die in een integer worden ingepakt. - Linux capabilities vervangen het oude root-of-niets-model door 40+ rechtenbits die je met
|combineert. - JWT-algoritmeheaders encoderen het hash-algoritme in een klein veld, waar bit-vergelijkingen gangbaar zijn in de bibliotheeklaag.
- Snowflake, ULID en UUIDv7 pakken timestamp, machine-ID en volgnummer in één 64-bit of 128-bit integer via left shifts.
- Redis
BITCOUNTenBITOPstellen bitwise-primitieven direct beschikbaar aan applicatiecode voor kardinaliteitsschatting en A/B-verdeling. - Beeldverwerking leest 32-bit RGBA-pixels en extraheert kanalen met
&en>>.
Bitsgewijze bewerkingen blijven O(1) op CPU-instructieniveau. Als je 32 booleans in één integer pakt, bespaar je 31 bytes geheugen, en (belangrijker) je kunt “zijn er van deze 32 flags gezet” in één != 0-test controleren.
Binaire grondbeginselen die je eerst nodig hebt
Deze gids gaat ervan uit dat je al weet hoe binair werkt. Als je een opfrisser nodig hebt, lees dan eerst onze Gids voor talstelselomrekening en kom daarna terug.
Een snelle woordenschatcheck voordat we beginnen:
- Een bit is een 0 of een 1.
- Een nibble is 4 bits (één hex-cijfer).
- Een byte is 8 bits.
- Een word is doorgaans 32 of 64 bits, afhankelijk van je CPU.
Integers in de meeste talen zijn in vaste breedtes: 8, 16, 32, 64. De breedte is erg belangrijk bij bitsgewijze bewerkingen, omdat shifts bits van het einde af kunnen duwen en de tekenbit op de meest linkse positie van signed integers zit.
Probeer dit nu. Open de Talstelsel-omrekenen, voer 170 in als decimaal, en bekijk de binaire uitvoer. Je ziet 10101010, een afwisselend patroon waar we hieronder meerdere keren op terugkomen.
De zes bitwise-operatoren
Elke gangbare taal geeft je dezelfde zes operatoren, soms met kleine syntaxverschillen. De symbolen &, |, ^, ~, <<, >> werken in JavaScript, Python, Go, Rust, C, C++, Java en C# ongewijzigd. JavaScript voegt er één toe: >>>, de unsigned right shift.
AND (&): bit-filter
Het uitvoerbit is 1 alleen als beide invoerbits 1 zijn.
| A | B | A & B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Zie AND als een poort: alleen bits die in beide operanden zijn gezet, overleven. Het meest voorkomende gebruik is masking: sommige bits bewaren en andere op nul zetten.
// Extract the low 4 bits (the rightmost nibble)
const value = 0b11010110; // 214
const low4 = value & 0x0F; // 0b00000110 = 6
// Check if a number is odd
const isOdd = (n) => (n & 1) === 1;
isOdd(7); // true
isOdd(42); // false
# Same in Python
value = 0b11010110
low4 = value & 0x0F # 6
def is_odd(n):
return (n & 1) == 1
OR (|): bit-zetter
Het uitvoerbit is 1 als een van beide invoerbits 1 is.
| A | B | A | B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
OR combineert flags. Als je READ = 1, WRITE = 2, EXECUTE = 4 hebt, is READ | WRITE gelijk aan 3, met beide rechten ingeschakeld.
const READ = 0b001;
const WRITE = 0b010;
const EXEC = 0b100;
const rw = READ | WRITE; // 0b011 = 3
READ, WRITE, EXEC = 0b001, 0b010, 0b100
rw = READ | WRITE # 3
XOR (^): bit-omschakelaar
Het uitvoerbit is 1 als de invoerbits van elkaar verschillen.
| A | B | A ^ B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
XOR heeft drie algebraïsche eigenschappen die sommige van de slimste trucs in de informatica mogelijk maken:
a ^ a = 0: alles wat je met zichzelf XOR’t, heft zichzelf op.a ^ 0 = a: XOR met nul is de identiteitsoperatie.a ^ b ^ a = b: XOR is zijn eigen inverse.
De laatste eigenschap verklaart waarom XOR opduikt in pariteitscontroles, stroomcijfers en de beruchte interviewvraag “vind het enige getal zonder duplicaat in een array”.
// Find the one unique number in an array where every other number appears twice
const findUnique = (arr) => arr.reduce((a, b) => a ^ b, 0);
findUnique([4, 1, 2, 1, 2]); // 4
from functools import reduce
from operator import xor
find_unique = lambda arr: reduce(xor, arr, 0)
find_unique([4, 1, 2, 1, 2]) # 4
NOT (~): bit-inverter
Unair ~ keert elk bit om: 0 wordt 1, 1 wordt 0.
~0b00001111 // -16 (JavaScript coerces to 32-bit signed)
~5 // -6
~5 # -6
// Go uses ^ as unary bitwise NOT, watch out
var x int8 = 5
fmt.Println(^x) // -6
Het resultaat van ~5 is -6 in elke gangbare taal, en dit verrast beginners. De reden is tweescomplement, wat we in de volgende sectie behandelen. Weet voor nu gewoon dat ~x gelijk is aan -(x + 1) in elke taal die tweescomplement voor negatieven gebruikt (wat ze allemaal doen).
Left shift (<<): vermenigvuldiger met machten van twee
x << n verschuift elk bit van x naar links met n posities, en vult nullen in aan de rechterkant. Wiskundig vermenigvuldigt dit met 2ⁿ.
1 << 0 // 1 (2^0)
1 << 1 // 2 (2^1)
1 << 3 // 8 (2^3)
1 << 10 // 1024 (2^10 = 1 KiB)
// Building bit flags
const FLAG_ADMIN = 1 << 0;
const FLAG_EDITOR = 1 << 1;
const FLAG_REVIEWER = 1 << 2;
Het handige aan 1 << n is dat het een getal creëert met slechts één bit gezet op positie n. Dat bit wordt een flag.
Let op overflow. In JavaScript is 1 << 31 gelijk aan -2147483648 (niet 2147483648) omdat JavaScripts bitwise-operatoren op 32-bit signed integers werken.
Right shift (>> vs >>>): delen of opvullen?
Right shift verplaatst bits naar rechts. De vraag is wat de vrijgekomen meest linkse posities vult.
>>(rekenkundige right shift) behoudt de tekenbit. Negatieve getallen blijven negatief.>>>(logische of unsigned right shift) vult met nullen. Alleen JavaScript heeft dit als aparte operator.
-8 >> 1 // -4 (sign bit preserved)
-8 >>> 1 // 2147483644 (sign bit treated as a data bit)
8 >> 1 // 4
8 >> 2 // 2
In C is het implementatie-afhankelijk of >> rekenkundig of logisch is voor signed types. De meeste compilers doen rekenkundig, maar vertrouw hier niet op zonder controle. Go vereist dat shiftbedragen unsigned integers zijn en behandelt signed en unsigned types expliciet. Python heeft geen >>> omdat het geen integers met vaste breedte heeft.
Tweescomplement: hoe computers negatieven weergeven
Als bits slechts 0 en 1 zijn, hoe encodeer je dan -5? Het antwoord waarop de wereld in de jaren 1960 is uitgekomen, is tweescomplement, en elke moderne CPU gebruikt het.
De naïeve aanpak (reserveer één bit voor het teken) heeft twee problemen. Ten eerste krijg je zowel +0 als -0, wat onhandig is. Ten tweede moeten optelling- en aftrekkingscircuits de tekenbit controleren, waardoor de hardware complexer wordt. Tweescomplement lost beide op.
De regel is kort:
- Neem de positieve binaire representatie.
- Keer elk bit om (dat is het “eenscomplement”).
- Tel 1 op.
Uitgewerkt voorbeeld: -5 encoderen in 8-bit tweescomplement:
5 in binary: 0000 0101
flip all bits: 1111 1010 (this is -6 in two's complement!)
add 1: 1111 1011 ← this is -5
Controleer het met onze talstelsel-omrekenen: voer 251 (decimaal) in bij de Talstelsel-omrekenen met grondtal 10, en de binaire uitvoer is 11111011. In een 8-bit signed context is 11111011 gelijk aan -5. In een 8-bit unsigned context is hetzelfde bitpatroon 251. De bits zijn identiek; de interpretatie verschilt.
Dit verklaart de eerdere verrassing van ~5 = -6. Bitwise NOT keert bits om, wat je het eenscomplement geeft. Tweescomplement is eenscomplement plus 1. Dus:
~x = -(x + 1) // identity in any two's complement language
~5 = -6
~(-3) = 2
Voor n-bit signed integers is het representeerbare bereik -2ⁿ⁻¹ tot 2ⁿ⁻¹ − 1. Een 8-bit signed integer dekt -128 tot 127. Een 32-bit signed integer dekt ruwweg -2,1 miljard tot +2,1 miljard.
Essentiële bitmanipulatiepatronen
Deze negen patronen dekken waarschijnlijk 95% van de bitmanipulatie die je ooit schrijft. Memoriseer ze en je herkent ze overal in systeemcode.
Een bit zetten: x | (1 << n)
Bit n inschakelen, andere bits ongewijzigd laten.
let flags = 0b0100;
flags = flags | (1 << 0); // 0b0101
Een bit wissen: x & ~(1 << n)
Bit n uitschakelen, andere bits ongewijzigd laten. ~(1 << n) is een masker met elk bit gezet behalve bit n.
let flags = 0b0111;
flags = flags & ~(1 << 1); // 0b0101
Een bit omschakelen: x ^ (1 << n)
Bit n omklappen ongeacht de huidige toestand.
let flags = 0b0100;
flags = flags ^ (1 << 2); // 0b0000
flags = flags ^ (1 << 2); // 0b0100 again
Een bit controleren: (x >> n) & 1
Geeft 1 terug als bit n is gezet, anders 0. Equivalente vorm: (x & (1 << n)) !== 0.
const flags = 0b0101;
const isBit2Set = (flags >> 2) & 1; // 1
Het laagste gezette bit isoleren: x & -x
Geeft een waarde met alleen het meest rechtse 1-bit van x. De truc werkt omdat -x in tweescomplement gelijk is aan ~x + 1, wat elk bit omkeert tot en inclusief het laagste gezette bit.
const x = 0b10110100;
const lowest = x & -x; // 0b00000100 = 4
Dit is de kerntechniek in Fenwick trees (Binary Indexed Trees) voor O(log n) prefix-sommen.
Gezette bits tellen (popcount)
Het aantal 1-bits in een integer tellen. De meeste talen hebben tegenwoordig een ingebouwde functie:
// JavaScript (BigInt or manual)
const popcount = (n) => {
let count = 0;
while (n) { count += n & 1; n >>>= 1; }
return count;
};
popcount(0b10110100); // 4
# Python 3.10+
(0b10110100).bit_count() # 4
// Go
import "math/bits"
bits.OnesCount(0b10110100) // 4
XOR-swap zonder tijdelijke variabele
Een klassieke nerdtruc: twee integers wisselen zonder een derde variabele. Gebruik dit nooit in productie (het is langzamer dan een tijdelijke variabele en werkt niet als a en b dezelfde geheugenlocatie delen), maar het is de moeite waard om te begrijpen.
let a = 5, b = 9;
a = a ^ b; // a = 5 ^ 9
b = a ^ b; // b = (5 ^ 9) ^ 9 = 5
a = a ^ b; // a = (5 ^ 9) ^ 5 = 9
// a = 9, b = 5
Machten van twee herkennen: (x & (x - 1)) === 0
Een macht van twee heeft precies één bit gezet. Aftrekken van 1 schakelt dat bit uit en zet elk lager bit in. De AND geeft nul alleen voor machten van twee (en 0 zelf, dus gebruik x > 0 als veiligheidscontrole).
const isPow2 = (x) => x > 0 && (x & (x - 1)) === 0;
isPow2(16); // true
isPow2(17); // false
Snelle oneven-controle: x & 1
In sommige talen sneller dan x % 2, identiek in andere na compileroptimalisatie. De moeite waard in hete loops of wanneer leesbaarheid er niet toe doet.
const isOdd = (x) => (x & 1) === 1;
Bitmask-flags in echte code
De bovenstaande patronen duiken elke dag in productiecode op. Hier zijn vier plaatsen waar je ze tegenkomt.
Feature flags in 32 booleans
In plaats van een struct met 32 booleans, pak je ze in één integer:
const FLAGS = {
DARK_MODE: 1 << 0,
NEW_NAV: 1 << 1,
AI_SUGGESTIONS: 1 << 2,
BETA_EDITOR: 1 << 3,
// ... up to 1 << 31
};
let userFlags = 0;
userFlags |= FLAGS.DARK_MODE | FLAGS.AI_SUGGESTIONS; // opt in
if (userFlags & FLAGS.AI_SUGGESTIONS) {
showSuggestions();
}
userFlags &= ~FLAGS.DARK_MODE; // opt out
Dit slaat 32 booleans op in 4 bytes en laat je elke subset met één AND opvragen. Databases zijn dol op dit patroon, want het is één kolom in plaats van 32.
Unix-bestandsrechten
chmod 755 is bitsgewijs. De drie octale cijfers komen overeen met drie triples van bits:
7 = 111 (owner: rwx)
5 = 101 (group: r-x)
5 = 101 (others: r-x)
Probeer het: open de Talstelsel-omrekenen, stel de bron in op octaal, voer 755 in, en kijk naar de binaire uitvoer 111101101. Zo slaat het bestandssysteem het rechtenveld op.
Alleen “group write” instellen:
const perms = 0o755;
const withGroupWrite = perms | 0o020; // 0o775
IP-subnetmasking
Gegeven 192.168.1.10/24, extraheer het netwerkadres door de AND toe te passen met het masker:
const ip = 0xC0A8010A; // 192.168.1.10
const mask = 0xFFFFFF00; // 255.255.255.0 (/24)
const network = ip & mask; // 0xC0A80100 = 192.168.1.0
Ingepakte ID’s: Snowflake
Twitter’s Snowflake pakt timestamp, machine-ID en volgnummer in een 64-bit integer:
┌─ 1 bit ─┬─── 41 bits ───┬─ 10 bits ─┬─ 12 bits ─┐
│ sign │ timestamp │ machine │ seq │
└─────────┴───────────────┴───────────┴───────────┘
Een ID encoderen is twee shifts en twee OR’s:
const id = (BigInt(timestamp) << 22n) |
(BigInt(machineId) << 12n) |
BigInt(sequence);
Decoderen is het omgekeerde: right shift en masker. Voor een uitgebreide vergelijking van wanneer je Snowflake, ULID of UUIDv7 kiest, zie onze vergelijking van gedistribueerde ID’s.
Taalspecifieke valkuilen
JavaScript: de 32-bit-omzettingsval
JavaScript zet operanden om naar 32-bit signed integers vóór elke bitsgewijze bewerking, en zet het resultaat daarna terug naar een Number. Elke waarde boven 2³¹ − 1 = 2147483647 loopt over:
2147483647 | 0 // 2147483647 (still fine)
2147483648 | 0 // -2147483648 (overflowed!)
4294967295 | 0 // -1 (all bits set, interpreted signed)
Gebruik voor 64-bit werk BigInt. Dit heeft zelfstandige bitwise-operatoren zonder breedtebegrenzing:
(2n ** 40n) | 1n // 1099511627777n
Bugs door operatorprioriteit
Dit is een van de meest voorkomende bitwise-bugs in de praktijk:
// Buggy: reads as (x & (1 == 0)) because == binds tighter than &
if (x & 1 == 0) { /* ... */ }
// Correct: parenthesize
if ((x & 1) == 0) { /* ... */ }
Vergelijkingsoperatoren binden strakker dan bitwise AND/OR/XOR in C, JavaScript, Python, Go en de meeste opvolgers. Zet haakjes als je twijfelt.
Vergelijkingstabel per taal
| Taal | Breedteomzetting | Negatieve >> | BigInt-ondersteuning |
|---|---|---|---|
| JavaScript | Forceert 32-bit signed; >>> is unsigned | rekenkundig | BigInt heeft aparte operatoren |
| Python | Onbeperkte precisie; geen vaste breedte | rekenkundig | Ingebouwd |
| Go | Strikt; shiftbedrag moet unsigned zijn | rekenkundig voor signed types | math/big |
| C/C++ | Volgt type; int, unsigned, enz. | implementatie-afhankelijk voor signed | Niet ingebouwd |
| Rust | Strikt; paniceert bij overflow in debug | rekenkundig voor signed types | u128 / externe crates |
Python’s infinitebrede benadering
Python-integers hebben geen vaste breedte, waardoor de tweescomplementlogica “oneindig” naar links uitbreidt. Daarom is ~5 gelijk aan -6 (niet 250 of 65530): Python behandelt het resultaat als een negatief integer, niet als een bitpatroon met vaste breedte. Als je wrap-around-semantiek nodig hebt, maskeer dan expliciet:
# Simulate 8-bit NOT
(~5) & 0xFF # 250
Prestatierealiteit in 2026
Het gangbare verhaal is dat bitsgewijze bewerkingen “altijd sneller” zijn. In 2026 is dat slechts half waar.
Compilers voeren de voor de hand liggende herschrijvingen al uit. Moderne optimizers zetten x * 2 automatisch om naar x << 1. x << 1 schrijven in applicatiecode voor snelheid is cargo-cult-prestatietuning. Het helpt niet en schaadt de leesbaarheid.
Waar bitsgewijze code echt wint:
- Hete loops in numerieke code: popcount, leading en trailing zero counts, bitboard-schaakengines.
- Compacte datastructuren: Bloom filters, roaring bitmaps, Fenwick trees.
- Hardwareregisters en memory-mapped I/O: embedded code, kernels, firmware.
- Cryptografische primitieven: AES, ChaCha20 en SHA zijn allemaal opgebouwd uit XOR, rotaties en shifts.
- Compressie en decompressie: Huffman-codering, run-length, ingepakte integers.
- Database-engines: bitmapindexen, ingepakte kolomformaten zoals Parquet dictionary encoding.
Waar het niet helpt: x % 2 vervangen door x & 1 in een bedrijfslogicafunctie die twee keer per request wordt uitgevoerd. De snelheidswinst is onmeetbaar; de leesbaarheidskosten zijn reëel.
Het ene geval waarbij bitmanipulatie altijd wint, is geheugengebruik. 32 flags inpakken in een int bespaart 31 bytes ten opzichte van 32 booleans. Op schaal (miljoenen gebruikersrecords, miljarden events) is dat het verschil tussen een cache-vriendelijke structuur en een workload die de L2-cache overbelast.
Beknopte naslag
| Bewerking | Operator | Voorbeeld | Resultaat | Typisch gebruik |
|---|---|---|---|---|
| AND | & | 0b1100 & 0b1010 | 0b1000 | Bits maskeren/extraheren |
| OR | | | 0b1100 | 0b1010 | 0b1110 | Flags combineren |
| XOR | ^ | 0b1100 ^ 0b1010 | 0b0110 | Omschakelen / verschil detecteren |
| NOT | ~ | ~0b1100 | ...11110011 | Omdraaien voor masker |
| Left shift | << | 1 << 3 | 8 | Vermenigvuldigen met 2ⁿ |
| Right shift | >> | 16 >> 2 | 4 | Delen door 2ⁿ (signed) |
| Unsigned right shift (JS) | >>> | -1 >>> 0 | 4294967295 | Als unsigned behandelen |
Bit n zetten | | | x | (1 << n) | Bit inschakelen | |
Bit n wissen | & ~ | x & ~(1 << n) | Bit uitschakelen | |
Bit n omschakelen | ^ | x ^ (1 << n) | Bit omklappen | |
Bit n controleren | & | (x >> n) & 1 | 0 of 1 | Bit testen |
| Laagste gezette bit | & - | x & -x | Bit isoleren | |
| Is macht van 2 | & | x > 0 && (x & (x-1)) == 0 | bool | Macht testen |
FAQ
Wat is het verschil tussen logische (&&) en bitsgewijze (&) AND?
Logische AND werkt op volledige boolean-waarden en short-circuit: false && expr evalueert expr nooit. Bitsgewijze AND werkt op individuele bits van integers en evalueert altijd beide kanten. Gebruik && voor voorwaarden, & voor bitmanipulatie.
Waarom is ~1 gelijk aan -2 in de meeste talen?
Bitwise NOT op 1 keert elk bit om om het eenscomplement te produceren. In de tweescomplement-integerrepresentatie geeft het omdraaien van alle bits van x als resultaat -(x + 1), dus ~1 is -2, ~0 is -1 en ~(-1) is 0. Deze identiteit geldt in JavaScript, Python, Go, C, Rust en elke andere taal die signed integers in tweescomplement opslaat.
Is x << 1 echt sneller dan x * 2?
In de praktijk niet. Elke moderne compiler herkent x * 2 en genereert dezelfde shift-instructie op machineniveau, zodat benchmarks geen meetbaar verschil laten zien op x86 of ARM. Gebruik x * 2 voor leesbaarheid; reserveer << voor gevallen waarbij je bewust in bits denkt, zoals het opbouwen van een bitmask of het inpakken van gestructureerde ID’s.
Ondersteunt JavaScript 64-bit bitsgewijze bewerkingen?
JavaScript ondersteunt geen 64-bit bitsgewijze bewerkingen met de standaard &, |, ^, <<, >> operatoren, omdat die operanden vóór de bewerking naar 32-bit signed integers forceren. Gebruik voor 64-bit of grotere waarden BigInt-literals zoals 1n << 40n, die bitsgewijze bewerkingen met onbeperkte precisie bieden via eigen bijbehorende operatoren.
Hoe tel ik het aantal gezette bits efficiënt?
Gebruik de ingebouwde functie van je taal: bits.OnesCount in Go, Integer.bitCount in Java, .bit_count() in Python 3.10+, popcount-intrinsics in C/C++. Deze komen overeen met één POPCNT-CPU-instructie op moderne x86 en ARM.
Wanneer gebruik ik bitmask-flags in plaats van een struct van booleans?
Gebruik bitmask-flags als je veel booleans compact moet opslaan (databases, netwerkprotocollen, bestandsformaten) of combinaties snel moet testen met één AND zoals flags & REQUIRED_MASK. Gebruik liever een struct van booleans als velden verschillende typen hebben, als je beschrijvende debug-uitvoer nodig hebt, of als leesbaarheid zwaarder weegt dan een paar bytes geheugen.
Wat gebeurt er als ik meer verschuif dan de bitbreedte?
Ongedefinieerd in C/C++. In JavaScript wordt het shiftaantal genomen mod 32, dus 1 << 32 is 1, niet 0. In Python is er geen breedte, dus 1 << 100 is gewoon een groter integer. Vertrouw nooit op overshift-gedrag; maskeer het shiftaantal zelf als dat nodig is.
Waarom geeft Python’s ~5 als resultaat -6 in plaats van 2?
Python-integers hebben geen vaste breedte, dus tweescomplement breidt conceptueel uit naar oneindig. ~5 is gelijk aan -(5 + 1) = -6, hetzelfde als elke andere tweescomplement-taal. Als je de 8-bit “omgekeerde” waarde 250 wilt, maskeer dan: (~5) & 0xFF.
Is XOR-encryptie veilig?
Een one-time pad met een echt willekeurige sleutel zo lang als het bericht is informatietheoretisch onkraakbaar. Dezelfde sleutel hergebruiken over meerdere berichten is catastrofaal onveilig, en standaard XOR-”encryptie” met een korte herhalende sleutel is triviaal kraakbaar. Echte cijfers zoals AES en ChaCha20 gebruiken XOR intern, maar als één stap onder velen.
Hoe representeer ik een negatief getal met tweescomplement met de hand?
Schrijf de positieve waarde in binair op de doelbreedte, keer elk bit om, en tel vervolgens 1 op. Voorbeeld: -5 in 8 bits = 00000101 → omdraaien naar 11111010 → 1 optellen → 11111011. Controleer met onze Talstelsel-omrekenen door 251 (de unsigned interpretatie van 11111011) te converteren en te bevestigen dat je 11111011 krijgt.
Bijbehorende tools en verder lezen
- Talstelsel-omrekenen: typ een getal en zie de bits veranderen
- Gids voor talstelselomrekening: vereiste achtergrondkennis over binair, octaal en hex
- UUID v4 vs v7 vs ULID vs Snowflake: bitpacking in gedistribueerde ID’s
- Aanbevolen aanpak voor beveiliging: rechten-bitmaps en hun valkuilen