In der Informatik bezeichnet eine Maske oder Bitmaske Daten, die für Bitoperationen , insbesondere in Bitfeldern , verwendet werden . Mithilfe einer Maske lassen sich mehrere Bits in einem Byte , Nibble , Wort usw. in einer einzigen Bitoperation setzen oder deaktivieren bzw. invertieren. Eine weitere Anwendung der Maskierung ist die Prädikation in der Vektorverarbeitung . Hierbei dient die Bitmaske dazu, auszuwählen, welche Elementoperationen im Vektor ausgeführt werden sollen (Maskenbit gesetzt) und welche nicht (Maskenbit gelöscht).
Gängige Bitmaskenfunktionen
Maskierungsbits1
Um bestimmte Bits zu setzen, kann die bitweiseOR Operation verwendet werden, wobei für ein einzelnes Bit Y gilt : und . Um sicherzustellen, dass ein Bit gesetzt ist, kann man also mit verwenden . Um ein Bit unverändert zu lassen, verwendet man mit . Y OR 1 = 1Y OR 0 = YOR1OR0
Beispiel: Maskierung des oberen Nibbles (Bits 4, 5, 6, 7), während das untere Nibble (Bits 0, 1, 2, 3) unverändert bleibt.
1001 0101 1010 0101 ODER 1111 0000 1111 0000 = 1111 0101 1111 0101
Maskierungsbits0
In der Praxis werden Bits häufiger „ausmaskiert “ (oder auf 0 maskiert 0) als „einmaskiert “ (oder auf 0 maskiert )1 . Wenn ein Bit ANDmit 0 maskiert wird, ist das Ergebnis immer 0, d. h Y AND 0 = 0. 0 = 0. Um die anderen Bits in ihrem ursprünglichen Zustand zu belassen, können sie ANDmit 10 maskiert werden.Y AND 1 = Y
Beispiel: Maskierung des oberen Nibbles (Bits 4, 5, 6, 7), während das untere Nibble (Bits 0, 1, 2, 3) unverändert bleibt.
1001 0101 1010 0101 UND 0000 1111 0000 1111 = 0000 0101 0000 0101
Den Status eines Bits abfragen
Mithilfe von Bitmasken lässt sich der Zustand einzelner Bits unabhängig von den anderen Bits einfach überprüfen. Dazu ANDwerden alle anderen Bits wie oben beschrieben bitweise deaktiviert und der Wert mit einem Nullwert verglichen 0. Ist der Wert gleich dem Nullwert 0, war das Bit deaktiviert; ist er ein anderer Wert, war das Bit aktiviert. Der Vorteil dieser Methode liegt darin, dass der tatsächliche Wert nicht bekannt sein muss, sondern nur, dass er nicht dem Nullwert entspricht 0.
Beispiel: Abfrage des Status des 4. Bits
1001 1 101 1001 0 101 UND 0000 1 000 0000 1 000 = 0000 1 000 0000 0 000
Umschalten von Bitwerten
Bisher wurde im Artikel behandelt, wie man Bits ein- und ausschaltet, jedoch nicht beides gleichzeitig. Manchmal ist der Wert irrelevant, er muss aber unbedingt umgekehrt werden. Dies lässt sich mit der XOR-Operation erreichen. Die XOR-Operation gibt genau dann einen Wert zurück, wenn eine ungerade Anzahl von Bits den Wert 0 hat. Sind also zwei entsprechende Bits 0, ist das Ergebnis 0, ist aber nur eines davon 0, ist das Ergebnis 0. Die Invertierung der Bitwerte erfolgt daher durch die XORXOR- Operation. WarXOR das ursprüngliche Bit 0 , gibt die XOR- Operation 0 zurück . War das ursprüngliche Bit 0, gibt die XOR-Operation 0 zurück . Beachten Sie außerdem, dass die Maskierung bitsicher ist, d. h. sie beeinflusst nicht maskierte Bits nicht, da die XOR-Operation den Wert 0 zurückgibt , genau wie die XOR-Operation . 111011XOR111 XOR 1 = 000 XOR 1 = 1XORY XOR 0 = YOR
Beispiel: Umschalten von Bitwerten
10011101 10010101 XOR 00001111 11111111 = 10010010 01101010
Um beliebige Einsen und Nullen in eine Teilmenge von Bits zu schreiben, schreibt man zuerst Nullen in diese Teilmenge und setzt dann die höherwertigen Bits:
Register = (Register & ~Bitmaske) | Wert;
Zusammenführen von Bits
Manchmal müssen bestimmte Bits kopiert werden, ohne andere Bits in einem Register oder Speicher zu verändern. Dies lässt sich beispielsweise wie folgt ausdrücken:
, oder
Ziel = (Ziel & ~Bitmaske) | (Quelle & Bitmaske);
In diesem Beispiel enthält die Bitmaske 0 an den Stellen, an denen die Zielbits erhalten bleiben, und 1 an den Stellen, an denen sie durch Quellbits ersetzt werden .
(Wenn die Quelle nur Bits enthält, die eingefügt werden sollen, kann der &-Bitmaskenteil weggelassen werden.)
Anwendungsbereiche von Bitmasken

Argumente für Funktionen
In Programmiersprachen wie C sind Bitfelder eine nützliche Möglichkeit, einer Funktion eine Reihe benannter boolescher Argumente zu übergeben. Beispielsweise gibt es in der Grafik-API OpenGLglClear() einen Befehl, der den Bildschirm oder andere Puffer löscht. Er kann bis zu vier Puffer löschen (Farb-, Tiefen-, Akkumulations- und Schablonenpuffer ), sodass die API-Entwickler ihm vier Argumente hätten zuweisen können. Ein Aufruf sähe dann aber folgendermaßen aus:
glClear ( 1 , 1 , 0 , 0 ); // So funktioniert glClear eigentlich nicht und das würde zu instabilem Code führen.was nicht sehr aussagekräftig ist. Stattdessen gibt es vier definierte Feldbits, GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT, und , GL_STENCIL_BUFFER_BITund glClear()wird als deklariert
void glClear ( GLbitfield bits );Ein Aufruf der Funktion sieht dann folgendermaßen aus:
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );Intern kann eine Funktion, die ein solches Bitfeld entgegennimmt, Binärdaten verwenden, andum die einzelnen Bits zu extrahieren. Eine Implementierung könnte beispielsweise glClear()so aussehen:
void glClear ( GLbitfield bits ) { if (( bits & GL_COLOR_BUFFER_BIT ) != 0 ) { // Farbpuffer löschen. } if (( bits & GL_DEPTH_BUFFER_BIT ) != 0 ) { // Tiefenpuffer löschen. } if (( bits & GL_ACCUM_BUFFER_BIT ) != 0 ) { // Akkumulationspuffer löschen. } if (( bits & GL_STENCIL_BUFFER_BIT ) != 0 ) { // Schablonenpuffer löschen. } }Der Vorteil dieses Ansatzes liegt im geringeren Overhead der Funktionsargumente. Da die minimale Datengröße ein Byte beträgt, würde die Aufteilung der Optionen in separate Argumente sieben Bit pro Argument verschwenden und mehr Stack-Speicher belegen. Stattdessen akzeptieren Funktionen typischerweise einen oder mehrere 32-Bit-Ganzzahlen mit jeweils bis zu 32 Optionsbits. Obwohl elegant, ist diese Lösung in der einfachsten Implementierung nicht typsicher . Da `A` GLbitfieldeinfach als `A` definiert ist unsigned int, würde der Compiler einen sinnlosen Aufruf von `A` glClear(42)oder sogar `B` zulassen glClear(GL_POINTS). In C++ wäre eine Alternative die Erstellung einer Klasse, die die von `glClear` akzeptierten Argumente kapselt und sauber in einer Bibliothek gekapselt werden könnte.
Inverse Masken
IP-ACLs (Access Control Lists) verwenden Masken, um festzulegen, welcher Datenverkehr erlaubt und welcher verboten werden soll. Zur Konfiguration von IP-Adressen auf Schnittstellen beginnen Masken mit 255, wobei die großen Werte links stehen: beispielsweise die IP-Adresse 203.0.113.129 mit der Maske 255.255.255.224 . Masken für IP-ACLs sind umgekehrt aufgebaut: beispielsweise die Maske 0.0.0.255 . Diese wird auch als inverse Maske oder Wildcard-Maske bezeichnet . Die Binärdarstellung der Maske (0 und 1) bestimmt, welche Adressbits bei der Verarbeitung des Datenverkehrs berücksichtigt werden. Ein 0 -Bit bedeutet, dass das Adressbit exakt übereinstimmen muss; ein 1- Bit in der Maske wird ignoriert.
Beispiel: Eine Netzwerkadresse (zu verarbeitender Datenverkehr): 192.0.2.0mit Maske: 0.0.0.255. Binär ist die Adresse 11000000.00000000.00000010.00000000und die Maske 00000000.00000000.00000000.11111111.
Anhand der Binärmaske lässt sich erkennen, dass die ersten drei Oktette exakt mit der gegebenen binären Netzwerkadresse übereinstimmen müssen 11000000.00000000.00000010. Die letzten drei Oktette werden von der Maske ignoriert. Somit 192.0.2.wird der gesamte Datenverkehr, der mit "" beginnt, erfasst. Mit dieser Maske werden daher Netzwerkadressen 192.0.2.1von 192.0.2.2551 bis 192.0.2.x1 verarbeitet.
Die Subtraktion der normalen Maske von 255.255.255.255ergibt die inverse ACL-Maske. In diesem Beispiel wird die inverse Maske für eine Netzwerkadresse 198.51.100.0mit der normalen Maske : ermittelt 255.255.255.0.
255,255,255,255 − 255,255,255,0 = 0,0,0,255 (normale Maske) (inverse Maske)
ACL-Äquivalente
Die Quelle/der Quell-Wildcard bedeutet "beliebig". 0.0.0.0/255.255.255.255
Die Quelle/das Wildcard-Zeichen ist dasselbe wie "Host ". 198.51.100.2/0.0.0.0198.51.100.2
Bildmasken

In der Computergrafik lassen sich transparente Bereiche eines Bildes, das vor einem Hintergrund platziert werden soll, mithilfe einer Binärmaske definieren. [ 1 ] Für jedes Bild existieren somit zwei Bitmaps : das eigentliche Bild, in dem die nicht benötigten Bereiche einen Pixelwert mit ausschließlich Nullen erhalten , und eine zusätzliche Maske . In dieser Maske erhalten die entsprechenden Bildbereiche einen Pixelwert mit ausschließlich Nullen, während die umgebenden Bereiche einen Wert mit ausschließlich Einsen erhalten. Im Beispiel rechts sind schwarze Pixel mit ausschließlich Nullen und weiße Pixel mit ausschließlich Einsen belegt.
Zur Laufzeit maskiert das Programm, um das Bild über den Hintergrund auf dem Bildschirm zu legen, zunächst die Bits der Bildschirmpixel an den gewünschten Koordinaten mithilfe einer bitweisen UND- Verknüpfung mit der Bildmaske. Dadurch bleiben die Hintergrundpixel der transparenten Bereiche erhalten, während die Bits der Pixel, die vom überlagerten Bild verdeckt werden, auf Null gesetzt werden.
Anschließend werden die Bildpixel mithilfe einer bitweisen ODER- Verknüpfung mit den Hintergrundpixeln des Programms gerendert . Dadurch werden die Bildpixel korrekt positioniert, während die umgebenden Hintergrundpixel erhalten bleiben. Das Ergebnis ist eine perfekte Überlagerung des Bildes mit dem Hintergrund.

Diese Technik wird zum Zeichnen von Mauszeigern , in typischen 2D-Videospielen für Spielfiguren, Projektile usw. ( Sprites ), für GUI- Symbole sowie für Videotitel und andere Bildmischungsanwendungen verwendet. Eine schnellere Methode besteht darin, die Hintergrundpixel einfach mit den Vordergrundpixeln zu überschreiben, falls deren Alpha-Wert 1 beträgt.
Obwohl sie verwandt sind (da sie für die gleichen Zwecke verwendet werden), handelt es sich bei transparenten Farben und Alphakanälen um Techniken, die keine Bildpixelmischung durch binäre Maskierung beinhalten.
Hashtabellen
Um eine Hashfunktion für eine Hashtabelle zu erstellen , wird häufig eine Funktion mit einem großen Definitionsbereich verwendet. Um einen Index aus der Ausgabe der Funktion zu erzeugen, kann ein Modulo verwendet werden, um die Größe des Definitionsbereichs an die Größe des Arrays anzupassen. Auf vielen Prozessoren ist es jedoch oft schneller, die Größe der Hashtabelle auf Zweierpotenzen zu beschränken und stattdessen eine Bitmaske zu verwenden.
Ein Beispiel für Modulo und Maskierung in C:
#include <stdint.h> #include <stdlib.h> #include <string.h>// eine Hash-Funktion uint32_t hashFunction ( char * token , size_t len , uint32_t bucketCount );int main ( void ) { const uint32_t NUM_BUCKETS = 0xFFFFFFFF ; // 2^32 - 1 const uint32_t MAX_RECORDS = 1 << 10 ; // 2^10 const uint32_t HASH_BITMASK = 0x3FF ; // 2^10 - 1 const size_t TOKEN_COUNT = 100 ; // Beispielgrößechar * tokens [] = ( char ** ) malloc ( sizeof ( char * ) * TOKEN_COUNT ); // Speicherverwaltung für Token...char token [] = "ein hashbarer Wert" ; uint32_t hashedToken = hashFunction ( token , strlen ( token ), NUM_BUCKETS );// Verwendung von Modulo: size_t index = hashedToken % MAX_RECORDS ;// Oder, unter Verwendung einer Bitmaske: size_t index = hashedToken & HASH_BITMASK ;tokens [ index ] = token ;// Den Speicher von den Token freigeben... free ( tokens ); return 0 ; }Siehe auch
- Affinitätsmaske
- Binärkodierte Dezimalzahl
- Bitfeld
- Bitmanipulation
- Bitweise Operation
- Subnetz
- Markierter Zeiger
- umask
Referenzen
- ^ „Mask R-CNN mit OpenCV“ . PyImageSearch . 19.11.2018 . Abgerufen am 05.04.2020 .