WebClub - Всероссийский Клуб Веб-разработчиков
WebClub.RU » Советы » Установка значения бита

Установка значения бита


Дата публикации: 10-04-2008

Чтобы установить определенный бит, используется операция включающей дизъюнкции (значение | значение). Допустим, текущее значение флага $value равно 3 (это означает, что установлен нулевой и первый биты), а вы хотите дополнительно установить второй бит (не забывайте, что нумерация начинается с нуля). Тогда можно воспользоваться операцией включающей дизъюнкции текущего значения флага с константой 4 (2 во второй степени):

$value = 3;

$value |= 4;

Теперь значение стало равно 7. В двоичном виде операция выглядит следующим образом:

0 0 0 0 0 1 1

| 0 0 0 0 1 0 0

= 0 0 0 0 1 1 1

Переключение бита

Переключение бита - установка его значения равным 1, если он был равен 0, и наоборот, - осуществляется операцией исключающей дизъюнкции (value ^ value). Если значение равно 3, а мы хотим переключить первый бит (который равен 1, поскольку в двоичной системе счисления число 3 выглядит как 0000011), то следует написать:

$value = 3;

$value ^= 2;

В результате получится 1. В двоичном виде:

0 0 0 0 0 1 0

^ 0 0 0 0 0 1 0

= 0 0 0 0 0 0 1

Сброс бита

Сброс бита осуществляется очень просто: сначала нужно убедиться, что он включен, а затем обратить его. Это требует двух поразрядных операций (value & ~value). Чтобы сбросить первый бит в значении 3, можно использовать следующие строки:

$value = 3;

$value $= ~2;

Проверка значения бита

Чтобы проверить, установлен ли бит, используется операция конъюнкции. Эта операция сравнивает два значения и возвращает 1 для тех позиций, где биты в обоих числах оказались равны 1. Скажем, чтобы проверить, установлен ли первый бит в константе 3, можно написать:

if(2 & 3)

//соответствующий код

Поразрядный сдвиг

Для сдвига битов вправо или влево можно использовать операторы сдвига >> и << (например, значение << количество_позиций). Так, сдвиг значения 1 влево на одну позицию даст в результате двоичное значение 10:

0 0 0 0 0 0 1

<< 0 0 0 0 0 1 0

= 0 0 0 0 0 1 0

Поразрядный сдвиг может использоваться для установки значений битов (см. пример).

Приоритет операторов

Помните, что приоритет поразрядных операторов ниже, чем приоритет арифметических операторов. Операторы в выражении 1 + 2 | 3 будут выполняться в следующем порядке: (1 + 2) | 3. Кроме того, необходимо помнить, что поразрядные операторы имеют более низкий приоритет, чем операторы сравнения. Будьте внимательны и избегайте условий вроде if(2 & 3 != 0). Вместо проверки на то, установлен ли второй бит в значении 3 (а он установлен), в данном выражении сначала проверяется значение условия 3 != 0, а это, конечно, правда (true). В результате мы получаем выражение 2 & 1, возвращающее 0, а это совсем не то, что мы хотели.

Пример

Вернемся к примеру с увлечениями пользователя, который мы использовали выше. Предположим, что в программе определены четыре возможных увлечения: чтение, программирование, сочинительство и путешествия. В начале каждому хобби мы поставим в соответствие свой бит:

  • чтение - 0

  • программирование - 1

  • сочинительство - 2

  • путешествия - 3

В двоичном виде эти значения представлены следующим образом:

Чтение: 0 0 0 0 0 0 1

Программирование: 0 0 0 0 0 1 0

Сочинительство: 0 0 0 0 1 0 0

Путешествия: 0 0 0 1 0 0 0

Определить виды увлечений в тексте сценария можно обычным поразрядным сдвигом:

define("HOBBY_READING":, 1 << 0);

define("HOBBY_PROGRAMMING", 1 << 1);

define("HOBBY_WRITING", 1 << 2);

define("HOBBY_HIKING", 1 << 3);

Если пользователь выбирает в качестве хобби сочинительство и программирование, можно создать комбинацию битов при помощи оператора | (включающая дизъюнкция):

$pattern = HOBBY_WRITING | HOBBY_PROGRAMMING;

После этого вы можете проверить, действительно ли пользователь выбрал сочинительство в качестве своего хобби, обратившись к значению соответствующего бита:

printf ("Сочинительство %s выбрано.", (HOBBY_WRITING & $pattern) ? "": "не");

Для сброса бита, связанного с сочинительством, можно использовать следующую строку:

$pattern &= -HOBBY_WRITING;

Проверка уровня прав доступа осуществляется с помощью функции $auth-> have_perm("admin"). В качестве параметра ей передается уровень прав доступа; в нашем примере это $auth->have_perm("admin"). Функция проверяет, имеет ли пользователь привилегию admin. Если пользователь имеет необходимые права доступа, то функция возвращает true, иначе - false.
У каждого пользователя есть соответствующие привилегии. В реализации класса Example_Auth информация о привилегиях записывается в таблицу auth_user базы данных MySQL. Вы уже видели это поле в текстах сценариев:
perms varchar (255)

Список допустимых уровней доступа определяется в классе, производном от Perm, в переменной класса $permissions. Для класса Example_Perm установлены следующие разрешения на доступ:

var $permissions = array(

"user" =>1

"author" =>2

"editor" =>4

"supervisor" =>8

"admin" =>16

);

Права доступа переводятся в двоичные значения внутренними функциями класса; при соответствующих вычислениях используются конъюнкция и дизъюнкция. Значения в определенном выше ассоциативном массиве определяют свою комбинацию битов для каждого уровня прав доступа. Хотя все это выглядит достаточно сложно, использование комбинации битов очень эффективно для представления подобных данных. В частности, этот механизм дает возможность работать с уровнями, наследующими права доступа более низких уровней. Если вы хорошо продумали соответствующие комбинации битов, уровень admin может автоматически получить все привилегии уровня user.

У значений, заданных по умолчанию, подобная модель поведения отсутствует: уровень admin отличается от уровня user, и пользователь, принадлежащий к группе admin, не получит доступа к функциональным возможностям, установленным в элементе $auth->have_perm("user"). Чтобы было понятнее, посмотрим, как библиотека PHPLib вычисляет комбинации битов.

  • Допустим, определенные возможности доступны только для уровня user. Этому уровню соответствует константа 1.

  • Пусть пользователю соответствует уровень доступа admin, которому соответствует число 16.

  • Указанные операнды соединяются конъюнкцией, в результате получается 0 (проверьте сами: print(16 & 1);). Результат (0) не совпадает с константой, определенной для уровня user (требуется 1), поэтому доступ невозможен.

Суть этих вычислений заключается в том, что библиотека PHPLib проверяет, установлен ли в комбинации разрядов, заданной в качестве аргумента функции $perm-> have_perms(), бит, соответствующий правам доступа данного пользователя. Такой механизм дает возможность определять сложные комбинации прав доступа.

Рассмотрим другой пример. Предположим, что имеется четыре уровня прав доступа: admin, editor_in_chief, editor и author (администратор, главный редактор, редактор, автор). Вы хотите, чтобы редактор (editor) не мог вносить на рассмотрение ответственных лиц никаких материалов (это прерогатива автора - author), но все прочие группы должны наследовать права доступа, установленные для более низких уровней. Окончательно система полномочий выглядит следующим образом:

  • admin : наследует editor_in_chief, editor, author

  • editor_in_chief: наследует editor, author

  • editor

  • author

Чтобы вычислить комбинацию битов для каждой группы пользователей, следует начать с нижнего уровня, author, с комбинации 1 (означающей, что установлен самый правый, нулевой бит). Если бы мы хотели, чтобы редактор наследовал уровень автора, мы бы использовали его комбинацию разрядов и установили следующий бит (1 | 2). Однако в данном примере мы хотим разделить права этих двух групп, поэтому мы задаем уровень editor как комбинацию разрядов, дающую значение 2 (двоичное 10).

Теперь, если редактор запрашивает страницу, доступную только для группы author, он не получает к ней доступа:

  • Требуемый уровень (author): 1.

  • Действительный уровень (editor): 2.

  • Конъюнкция 1 и 2 (1 & 2) равна 0, а это не соответствует требуемому уровню.

Следующий, более высокий уровень (второй бит, то есть третий справа) - это editor_in_chief, наследующий уровням editor и author. Это означает, что в комбинации разрядов уровня главного редактора должны быть установлены нулевой и первый биты, а мы дополнительно устанавливаем второй бит (2 во второй степени, или 4): 1 | 2 | 4. В результате получаем 7.

Проверим правильность полученного результата:

  • Требуемый уровень (editor): 2.

  • Текущий уровень (editor_in_chief): 7.

  • Конъюнкция 7 и 2 (7 & 2) дает 2, то есть требуемый уровень.

Осталось рассмотреть уровень администратора, который также наследует всем низшим уровням. Следует использовать выражение 7 | 8 (константа 8, или 2 в третьей степени, используется для установления третьего бита). Результат равен 15. Проверяем:

  • Требуемый уровень (editor_in_chief): 7.

  • Текущий уровень (admin): 15.

  • Конъюнкция 15 и 7 (15 & 7) дает нам 7, что соответствует требуемому уровню.

Таким образом, наши права доступа определяются следующим образом:

define("PHPLIB_PERM_AUTHOR", 1 | 0);

define("PHPLIB_PERM_EDITOR", 1 | 0);

define("PHPLIB_PERM_EDITOR_IN_CHIEF" 1 | 2 | 4);

define("PHPLIB_PERM_ADMIN", 1 | 2 | 4 | 8);

var $permissions = array(

"author" => PHPLIB_PERM_AUTHOR,

"editor" => PHPLIB_PERM_EDITOR,

"editor_in_chief" =>PHPLIB_PERM_EDITOR_IN_CHIEF,

"admin" => PHPLIB_PERM_ADMIN

);

Заключение

В этой главе вы познакомились с основными классами и способами применения библиотеки PHPLib. Она является мощным инструментом, обеспечивающим решение многих проблем, которые неизбежно возникают при создании Web-приложений. Этой библиотекой легко пользоваться, если вы позаботитесь о том, чтобы предварительно создать на ее основе продуманный механизм, отвечающий вашим потребностям. Библиотека PHPLib - прекрасный каркас для реализации процедур управления всеми аспектами сеансов работы пользователей и аутентификации.

В следующей главе мы рассмотрим образец использования библиотеки PHPLib в реальном приложении. Кроме того, вы познакомитесь еще с одним классом - Template, - позволяющим добиться более полной развязки кода и макета.

Домен продается

Популярное

Не так давно в сети появился новый сервис, под названием Dead Man Zero. Этот сервис сделал...
Рынок социальных площадок уже давно стал стабильным. Несмотря на то, что время от времени...
Artisteer 4 – единственный в своем роде продукт, позволяющий автоматизировать работу над созданием...
Октябрь 2018 (14)
Февраль 2017 (3)
Январь 2017 (1)
Август 2016 (1)
Май 2016 (2)
Ноябрь 2015 (1)

Карта сайта: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41

Друзья сайта



Случайная цитата

Alan J. Perlis:

"Низкоуровневый язык — это когда требуется внимание к вещам, которые никак не связаны с программами на этом языке."

Опрос

Какими социальными сетями Вы пользуетесь?

Vkontakte.ru
Одноклассники
Мой Мир - mail.ru
Google Plus
Facebook
ЖЖ
Другие
Не пользуюсь