Skip to content

Comunidade Portuguesa de PHP

Narrow screen resolution Wide screen resolution Increase font size Decrease font size Default font size default color black color cyan color green color red color
Home arrow Tutoriais arrow Avançados arrow Operadores Bit-a-Bit (Bitwise Operators)
Operadores Bit-a-Bit (Bitwise Operators) PDF Imprimir e-mail
Classificação: / 12
FracoBom 
Escrito por Tiago Lopes   
15-Mar-2007

Índice


1. O que são/para que servem.
1.2. Operadores Bit-a-Bit
1.2.1. AND (E)
1.2.2. OR (OU)
1.2.3. NOT (NÃO)
1.2.4. XOR (XOR)
1.2.5. Shifts
1.2.5.1. Shift Left (Deslocar à esquerda)
1.2.5.2. Shift Right (Deslocar à direita)
2. Exemplo
3. Conclusão

1. O que são/para que servem.

Convém ter especial atenção para não confundir Operadores Bit-a-Bit com Operadores de Comparação, possuem funcionalidades distintas. Operadores de Comparação, tal como o nome indica, são operadores que servem para comparar dois dados retornando o valor boleano TRUE (ou 1) caso a comparação seja verdadeira, ou então, FALSE (ou 0) caso a comparação seja falsa.

Segundo o Manual de PHP (http://www.php.net/) "Operadores bit-a-bit permitem que você accione ou desligue bits específicos dentro de um inteiro. Se ambos os parâmetros da esquerda e da direita forem strings, esses operadores irão trabalhar nos caracteres dessa string."

Um bit é a unidade mais pequena que pode ser representada num computador, um bit só pode conter dois valores, 0 (zero) ou 1 (um). Os bits podem ser agrupados, sendo que, 8 bits correspondem a 1byte, 1024 bytes equivalem a 1 kilobyte, 1024 kilobytes representam 1 Megabyte, etc.

1.2 Operadores Bit-a-Bit

1.2.1 AND

O operador AND é representado por "&". Uma expressão onde é utilizada o operador AND, para ser verdadeira (TRUE) os bits têm ambos de possuir o valor 1. Em caso de um, ou os dois serem 0 a expressão devolve o valor 0. Como qualquer valor multiplicado por 0 é igual a 0, o operador AND é muitas vezes associado à multiplicação.

Tabela da verdade:

0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1

Exemplo: $a = $b & $c;
Supondo que $b = 10101011 e $c = 10000111:

$a =
10101011 &
10000111
--------------------
10000011
(...)
$a = 10000011;


1.2.2 OR


O operador OR é representado por "|". Uma expressão para ser verdadeira pelo menos um dos bits tem de ser 1, ou seja, só se os dois bits forem igual a 0 é que uma expressão é falsa.

Tabela da verdade:

0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
1 OR 1 = 1

Exemplo: $a = $b | $c;
Supondo que $b = 10101011 e $c = 10000111:

$a =
10101011 |
10000111
--------------------
10101111
(...)
$a = 10101111;


1.2.3 NOT

O operador NOT é um operador unário e é representado por "~". A operação exercida por este operador é de negação lógica sobre os bits, isto é, torna falso onde é verdadeiro e torna verdadeiro onde é falso.

Tabela da verdade:

NOT 1 = 0
NOT 0 = 1


Exemplo: $a = ~$b;
Supondo que $b = 10101011;

$a = ~(10101011);
(...)
$a = 01010100;


1.2.4 XOR

O operador XOR (Ou Exclusivo) é representado por "^". Com este operador, se os bits forem diferentes os bits resultantes são verdadeiros.

Tabela da verdade:

0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0


Exemplo: $a = $b ^ $c;
Supondo que $b = 10101011 e $c = 10000111:

$a =
10101011 ^
10000111
-------------------------------
00101100
(...)
$a = 00101100;


1.2.5. Shifts

O operador Shift desloca N bits à esquerda ou direita dependendo se for utilizado Shift Left ou Shift Right. Devido à rapidez, são muitas vezes usadas na programação como multiplicador ou divisor como substituição dos operadores "*" e "/".

1.2.5.1 Shift Left (Deslocar à esquerda)

O operador Shift Left desloca à esquerda N bits. Pode-se entender o shift left como uma multiplicação por 2 elevado a N. É de salientar que um número elevado a 0 é igual a 1, logo, o shift left de 0 equivale à multiplicação por 1.

Exemplo: $a = 10101011;

$a << 0 = 10101011;
$a << 1 = 01010110;
$a << 2 = 10101100;
$a << 3 = 01011000;
$a << 4 = 10110000;
$a << 5 = 01100000;
(...)

1.2.5.2 Shift Right (Deslocar à direita)

O operador Shift Right desloca à direita N bits. Pode-se entender o Shift Right como uma divisão por 2 elevado a N.

Exemplo: $a = 10101011;

$a >> 0 = 10101011;
$a >> 1 = 01010101;
$a >> 2 = 00101010;
$a >> 3 = 00010101;
$a >> 4 = 00001010;
$a >> 5 = 00000101;
(...)

2. Exemplo

Um portal possui um sistema de autenticação e necessita de definir diferentes credenciais para cada utilizador. Isto é, os utilizadores 1 e 3 podem aceder a áreas do portal que os utilizadores 2 e 4 não podem. Dentro da área reservada aos utilizadores 1 e 3, o utilizador 3 apenas pode visualizar enquanto que o utilizador 1 pode também adicionar e remover informação.

Agora que o problema foi definido, poderá ser resolvido facilmente se for usado bitwise operators.


Nota: Este exemplo não faz referência ao sistema de autenticação, apenas as credenciais serão focalizadas.

 

<?php

session_start( );

// Num ficheiro, define-se as diversas acções/credenciais que se pode realizar no portal.
define( 'TEM_ACESSO_AREA1', 0x01 );
define( 'TEM_ACESSO_AREA2', 0x02 );
define( 'PODE_VER', 0x04 );
define( 'PODE_REMOVER', 0x08 );
define( 'PODE_ADICIONAR', 0x16 );


/*
Na base de dados, a tabela com os valores referentes ao utilizador e palavra-passe poderia existir
um terceiro campo com as credenciais.
Neste exemplo, irei escrever directamente neste script as credenciais dos 4 utilizadores.
*/

$utilizador_1 = ( TEM_ACESSO_AREA1 | PODE_VER | PODE_REMOVER | PODE_ADICIONAR );
$utilizador_2 = ( TEM_ACESSO_AREA2 );
$utilizador_3 = ( TEM_ACESSO_AREA1 | PODE_VER );
$utilizador_4 = ( TEM_ACESSO_AREA2 );

/*
Imaginando que o sistema de autenticação gerava uma variável de sessão com o nome do utilizador em
questão, então:
(Neste caso, utilizador_1 ate utilizador_4)
*/

$credencial = $$_SESSION['utilizador'];

/*
Na atribuição acima foi utilizada uma variável dinâmica $$<nome_variável>, supondo que a variável
$_SESSION['utilizador'] tinha o valor "utilizador_1", então o resultado seria:
$credencial = $utilizador_1;
neste caso, o mesmo que:
$credencial = ( TEM_ACESSO_AREA1 | PODE_VER | PODE_REMOVER | PODE_ADICIONAR );
*/

// Agora, pode-se verificar se o utilizador tem credenciais para executar determinada acção usando
o seguinte conceito:

if( $credencial & TEM_ACESSO_AREA1 ) {
    // O utilizador tem acesso à area1
    if( $credencial & PODE_VER ) {
        // O utilizador tem acesso à area1 e pode ver
    }
    else {
        // O utilizador não tem credenciais suficientes para ver
    }
}
else {
    // O utilizador não possui credenciais suficientes
}

if( $credenciais & TEM_ACESSO_AREA2 ) {
    // O utilizador tem acesso à area1
}

// etc, etc, etc...

?>

 

Algumas explicações extra:

define( 'TEM_ACESSO_AREA1', 0x01 );
define( 'TEM_ACESSO_AREA2', 0x02 );
define( 'PODE_VER', 0x04 );
define( 'PODE_REMOVER', 0x08 );
define( 'PODE_ADICIONAR', 0x16 );
...
define('<constante>', <múltiplos de 2>);

<múltiplos de 2> :
0x01, 0x02, 0x04, 0x08, 0x16, 0x32, 0x64, 0x128, ...

Para "automatizar" também se poderia utilizar o shift left (relembro que é o mesmo que a multiplicação por 2 elevado a N):

define('TEM_ACESSO_AREA1', 1);
define('TEM_ACESSO_AREA2', TEM_ACESSO_AREA1 << 1);
define('PODE_VER', TEM_ACESSO_AREA1 << 2);
define('PODE_REMOVER', TEM_ACESSO_AREA1 << 3);
define('PODE_ADICIONAR', TEM_ACESSO_AREA1 << 4);
define('<acção>', TEM_ACESSO_AREA1 << <valor_anterior>+1);


3. Conclusão:

Espero que este tutorial tenha ajudado a compreender operadores Bit-a-Bit, principalmente quando são usados para trabalhar com flags (exemplo dado).
Mais informação sobre bitwise operators em: http://www.php.net/manual/pt_BR/language.operators.bitwise.php
Para qualquer dúvida, sugestão ou critica: http://forum.php-pt.com/


 Contacto do autor:

 

Tiago Lopes ( Este endereço de e-mail está protegido contra spam bots, pelo que o JavaScript terá de estar activado para que possa visualizar o endereço de email )
http://tiago.ptspot.co
Actualizado em ( 19-Mar-2007 )
 
< Artigo anterior   Artigo seguinte >

Entrada






Esqueceu a senha?
Sem conta? Criar Conta!

Newsletter

Subscreva a nossa newsletter.