Posts Tagged ‘php’

Operador XOR no PHP

maio 21st, 2008

Há alguns meses estava precisando criar uma classe de criptografia e quando eu fui desenvolver eu não encontrei nenhuma criptografia veloz o suficiente, até que o Luan me mostrou uma excelente utilização para o XOR. Este operador é muito parecido com o OR, porém a sua leitura é: “OU um OU outro” e não “UM ou OUTRO” como o OR. Confira a tabela abaixo exemplificando:

false ^ false = false
false ^ true = true
true ^ true = false
true ^ false = true

Legal não? só é verdadeiro se os valores forem diferentes.

Como exemplo vamos pegar 2 valores binários, como sendo uma chave e um valor:

valor: "11010110"
chave: "10011101"

Vamos operar cada bit usando o XOR, isso irá resultar o binário “encriptado”

11010110 ^ (valor)
10011101 = (chave)
01001011    (valor encriptado)

Na terceira linha obtivemos o valor encriptado, só para demonstrar, vamos usar esse valor encriptado e dar um XOR com a chave novamente.

01001011 ^ (valor encriptado)
10011101 = (chave)
11010110   (valor novamente)

Não precisa de mais exemplos certo? é uma forma fraca, porém muito veloz de gerar criptografia, e perfeita para usarmos em coisas simples, como a criptografia de URL’s e Salts

Mas não pense que programar isso é complexo, o PHP permite que façamos esse processo usando dois caracteres.

"a" ^ "b" = "?", logo
"?" ^ "b" = "a"

Com isso vou mostrar uma classe de criptografia extremamente simples:

class Crypt {
    static $chave = "xy";
    static function StringXor($a,$b) {
        if ($a=='') return '';
        $retorno = ""; $i = strlen($a)-1; $j = strlen($b);
        do{
            $retorno .= ($a{$i} ^ $b{$i % $j});
        }while ($i--);
        return strrev($retorno);
    }
    static function Encrypt($string) {
        return base64_encode(Crypt::StringXor($string, Crypt::$chave));
    }
    static function Decrypt($string) {
        return Crypt::StringXor(base64_decode($string), Crypt::$chave);
    }
}

O que essa classe faz basicamente é percorrer as strings da chave e do valor passado, calculando para cada caractere o seu valor encriptado, e ao final é codificado usando-se base64 para que não fique com caracteres inválidos na string.

Um exemplo:

texto = "andre"
chave = "xy"
resultado:
a ^ x
n ^ y
d ^ x
r ^ y
e ^ x

Código php:

$a = Crypt::Encrypt("andre");
echo "Encriptado:";
$b = Crypt::Decrypt($a);
echo "Decriptado: $b";

Saída:

Encriptado: GRccCx0=
Decriptado: andre

é isso, testem, entendam e qualquer coisa pergunte.