В информатике маска или битовая маска — это данные , которые используются для побитовых операций , особенно в битовых полях . Используя маску, несколько битов в байте , полубайте , слове и т. д. могут быть включены или выключены, либо инвертированы из включенного в выключенное состояние (или наоборот) за одну побитовую операцию. Дополнительное использование маскировки включает в себя предикацию при векторной обработке , где битовая маска используется для выбора, какие операции с элементами в векторе должны выполняться (бит маски включен), а какие нет (бит маски сброшен).
Чтобы включить определенные биты, можно использовать побитовую операцию, следуя OR
принципу и Y OR 1 = 1
. Y OR 0 = Y
Поэтому, чтобы убедиться, что бит включен, OR
можно использовать файл 1
. Чтобы оставить немного неизменным, OR
используется с расширением 0
.
Пример: Маскирование старшего полубайта (биты 4, 5, 6, 7), оставляя младший полубайт (биты 0, 1, 2, 3) неизменным .
1001 0101 1010 0101 ИЛИ 1111 0000 1111 0000 = 1111 0101 1111 0101
На практике чаще всего биты «маскируются » (или маскируются в 0
), чем «маскируются » (или маскируются в 1
). Когда бит AND
изменяется на 0, результат всегда равен 0, Y AND 0 = 0
т.е. Чтобы оставить остальные биты такими, какими они были изначально, их можно AND
изменить с 1
помощьюY AND 1 = Y
Пример: маскирование старшего полубайта ( биты 4, 5, 6, 7), оставляя младший полубайт (биты 0, 1, 2, 3) неизменным.
1001 0101 1010 0101И 0000 1111 0000 1111 = 0000 0101 0000 0101
Можно использовать битовые маски, чтобы легко проверять состояние отдельных битов независимо от других битов. Для этого побитовое отключение всех остальных битов AND
производится, как обсуждалось выше, и значение сравнивается с 0
. Если оно равно 0
, то бит выключен, но если значение любое другое, то бит включен. Что делает это удобным, так это то, что нет необходимости выяснять, каково на самом деле значение, просто это не так 0
.
Пример: Запрос состояния 4-го бита
1001 1 101 1001 0 101И 0000 1 000 0000 1 000 = 0000 1 000 0000 0 000
До сих пор в статье рассматривалось, как включать и выключать биты, но не то и другое одновременно. Иногда не имеет особого значения, какое значение имеет значение, но его необходимо сделать противоположным тому, какое оно есть в данный момент. Этого можно добиться с помощью операции XOR
(исключающее или) . XOR
возвращает значение 1
тогда и только тогда, когда нечетное число бит равно 1
. Следовательно, если два соответствующих бита равны 1
, результатом будет 0
, но если только один из них равен 1
, результат будет 1
. Поэтому инверсия значений битов выполняется путем XOR
их ввода с помощью 1
. Если исходный бит был 1
, он возвращается 1 XOR 1 = 0
. Если исходный бит был, 0
он возвращает 0 XOR 1 = 1
. Также обратите внимание, что XOR
маскирование является битобезопасным, то есть оно не влияет на немаскированные биты Y XOR 0 = Y
, поскольку OR
.
Пример: переключение значений битов
10011101 10010101Исключающее ИЛИ 00001111 11111111 = 10010010 01101010
Чтобы записать произвольные 1 и 0 в подмножество битов, сначала запишите 0 в это подмножество, а затем установите старшие биты:
регистр = (регистр и ~битовая маска) | ценить;
В языках программирования, таких как C , битовые поля являются полезным способом передачи набора именованных логических аргументов в функцию. Например, в графическом API OpenGL есть команда, glClear()
очищающая экран или другие буферы. Он может очищать до четырех буферов (буфер цвета, глубины, накопления и трафарета ), поэтому авторы API могли использовать четыре аргумента. Но тогда вызов к нему будет выглядеть так
glClear ( 1 , 1 , 0 , 0 ); // На самом деле glClear работает не так, и это может привести к нестабильности кода.
что не очень наглядно. Вместо этого есть четыре определенных бита поля: GL_COLOR_BUFFER_BIT
, GL_DEPTH_BUFFER_BIT
, GL_ACCUM_BUFFER_BIT
, и GL_STENCIL_BUFFER_BIT
объявляется glClear()
как
void glClear ( биты GLbitfield );
Тогда вызов функции выглядит так
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Внутри функция, принимающая такое битовое поле, может использовать двоичный код and
для извлечения отдельных битов. Например, реализация glClear()
может выглядеть так:
void glClear ( GLbitfield bits ) { if (( bits & GL_COLOR_BUFFER_BIT ) != 0 ) { // Очистить буфер цвета. } if (( bits & GL_DEPTH_BUFFER_BIT ) != 0 ) { // Очистка буфера глубины. } if (( bits & GL_ACCUM_BUFFER_BIT ) != 0 ) { // Очистка буфера накопления. } if (( bits & GL_STENCIL_BUFFER_BIT ) != 0 ) { // Очищаем буфер трафарета. } }
Преимущество этого подхода заключается в том, что уменьшаются накладные расходы на аргументы функции. Поскольку минимальный размер данных составляет один байт, разделение опций на отдельные аргументы привело бы к потере семи бит на аргумент и заняло бы больше места в стеке. Вместо этого функции обычно принимают одно или несколько 32-битных целых чисел, каждое из которых содержит до 32 битов опций. Несмотря на элегантность, в простейшей реализации это решение не является типобезопасным . A GLbitfield
просто определяется как unsigned int
, поэтому компилятор допускает бессмысленный вызов glClear(42)
или даже glClear(GL_POINTS)
. В C++ альтернативой было бы создание класса для инкапсуляции набора аргументов, которые glClear мог бы принять и которые можно было бы аккуратно инкапсулировать в библиотеке.
Маски используются с IP-адресами в IP ACL (списках контроля доступа), чтобы указать, что следует разрешить, а что запретить. Чтобы настроить IP-адреса на интерфейсах, маски начинаются с 255 и имеют большие значения слева: например, IP-адрес 203.0.113.129 с маской 255.255.255.224 . Маски для IP ACL являются обратными: например, маска 0.0.0.255 . Иногда ее называют обратной маской или подстановочной маской . Когда значение маски разбивается на двоичные значения (0 и 1), результаты определяют, какие биты адреса следует учитывать при обработке трафика. 0 - бит указывает, что бит адреса должен учитываться (точное совпадение); 1 - бит в маске означает «неважно». Эта таблица дополнительно объясняет эту концепцию.
Пример маски:
сетевой адрес (трафик, который необходимо обработать): 192.0.2.0
маска: 0.0.0.255
сетевой адрес (двоичный): 11000000.00000000.00000010.00000000
маска (двоичная): 00000000.00000000.00000000.11111111
Судя по двоичной маске, видно, что первые три набора ( октета ) должны точно соответствовать заданному двоичному сетевому адресу (11000000.00000000.00000010). Последний набор цифр состоит из слова «все равно» (.11111111). Таким образом, весь трафик, начинающийся с « 192.0.2. », соответствует, поскольку последний октет — «не важно». Таким образом, с помощью этой маски обрабатываются сетевые адреса с 192.0.2.1 по 192.0.2.255 ( 192.0.2.x ).
Вычтите нормальную маску из 255.255.255.255 , чтобы определить обратную маску ACL. В этом примере обратная маска определяется для сетевого адреса 198.51.100.0 с нормальной маской 255.255.255.0 .
255.255.255.255 – 255.255.255.0 (обычная маска) = 0.0.0.255 (инверсная маска)
Эквиваленты ACL
Источник/подстановочный знак источника 0.0.0.0/255.255.255.255 означает «любой» .
Источник/подстановочный знак 198.51.100.2/0.0.0.0 такой же, как « хост 198.51.100.2 » .
В компьютерной графике , когда данное изображение предназначено для размещения на фоне, прозрачные области можно указать с помощью двоичной маски. [1] Таким образом, для каждого предполагаемого изображения фактически существует два растровых изображения : фактическое изображение, в котором неиспользуемым областям присваивается значение пикселя со всеми битами , установленными в 0, и дополнительная маска , в которой задаются соответствующие области изображения. значение пикселя, все биты которого установлены в 0, а окружающие области — значение всех бит, установленное в 1. В примере справа черные пиксели имеют биты «все ноли», а белые пиксели — биты «все единицы».
Во время выполнения , чтобы поместить изображение на экран поверх фона, программа сначала маскирует биты пикселей экрана маской изображения в нужных координатах, используя побитовую операцию И. Это сохраняет фоновые пиксели прозрачных областей и обнуляет биты пикселей, которые будут скрыты перекрывающимся изображением.
Затем программа визуализирует биты пикселей изображения, объединяя их с битами пикселя фона с помощью побитовой операции ИЛИ . Таким образом, пиксели изображения размещаются соответствующим образом, сохраняя при этом фон, окружающий пиксели. В результате получается идеальное сочетание изображения с фоном.
Этот метод используется для рисования курсоров указывающих устройств, в типичных двухмерных видеоиграх для персонажей, маркеров и т. д. (спрайты ) , для значков графического пользовательского интерфейса , а также для титров видео и других приложений для микширования изображений. Более быстрый метод — просто перезаписать пиксели фона пикселями переднего плана, если их альфа = 1.
Несмотря на то, что прозрачные цвета и альфа-каналы связаны между собой (поскольку они используются для одних и тех же целей), они представляют собой методы, которые не включают смешивание пикселей изображения посредством двоичной маскировки.
Для создания хеш-функции для хеш-таблицы часто используется функция, имеющая большой домен. Чтобы создать индекс на выходе функции, можно взять модуль, чтобы уменьшить размер домена до размера массива; однако на многих процессорах зачастую быстрее ограничить размер хеш-таблицы степенями двух размеров и вместо этого использовать битовую маску.
Пример как по модулю, так и маскировки в C:
#include <stdint.h> #include <string.h> 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 символ ** token_array = NULL ; // Обрабатываем выделение памяти для token_array… char token [] = "некоторое хэшируемое значение" ; uint32_t hashed_token = hash_function ( токен , strlen ( токен ), NUM_BUCKETS ); // Использование по модулю size_t index = hashed_token % MAX_RECORDS ; // ИЛИ // Использование битовой маски size_t index = hashed_token & HASH_BITMASK ; * ( массив_токена + индекс ) = токен ; // Освободить память из token_array … return 0 ; }