任何人都可以向我解释这个PHP代码吗?来自单行代码的意外结果

时间:2012-02-16 11:02:36

标签: php operators bit-manipulation

有人可以解释一下PHP在这里做了什么以及是否有可能获得可预测的结果?

这可以用于隐藏消息吗?

echo '1' | 'z';

4 个答案:

答案 0 :(得分:2)

如果在两个字符串之间执行按位运算,则字符串中的每个字符表示一个8位的八位字节。然后按字符每个字符完成按位操作。这就是将字符转换为整数,就像使用ord函数一样,然后将结果转换为字符串(与chr相当)。

 echo '1' | 'z';

相同
 echo chr(ord('1') | ord('z'));

取自PHP手册:

  

Example #2 Bitwise XOR operations on strings

<?php
echo 12 ^ 9; // Outputs '5'

echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
                 // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8

echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
                        // 'a' ^ 'e' = #4

echo 2 ^ "3"; // Outputs 1
              // 2 ^ ((int)"3") == 1

echo "2" ^ 3; // Outputs 1
              // ((int)"2") ^ 3 == 1
?>

相同的转换逻辑适用于OR |运算符:

<?php
echo 12 | 9; // Outputs '13'

echo "12" | "9"; // Outputs the 9 character (ascii 57)
                 // ('1' (ascii 49)) | ('9' (ascii 57)) = #57

echo "hallo" | "hello"; // Outputs the ascii values #104 #101 #108 #108 #111
                        // 'a' | 'e' = #101

echo 2 | "3"; // Outputs 3
              // 2 | ((int)"3") == 3

echo "2" | 3; // Outputs 3
              // ((int)"2") | 3 == 3
?>

如果在字符串和整数之间执行按位运算,则首先将字符串转换为整数。

答案 1 :(得分:2)

它使用按位OR运算符

'1' = ASCII 0x31 = Binary 00110001
'z' = ASCII 0x7A = Binary 01111010

ORing两者给出了

  00110001  1
| 01111010  z
= 01111011  {

是0x7B 这是ASCII字符{

正如已经指出的那样,为了使其可逆,应该使用XOR而不是OR

XORing the two give

  00110001  1
^ 01111010  z
= 01001011  K

是0x4B 这是ASCII字符K

倒车:

  01001011  K
^ 01111010  z
= 00110001  1

修改

这不是一个特别强大的代码,但是:

$plainTextMessage = "My secret message";
$secretCharacter = 'z';

$codedMessage = '';
for($i = 0; $i < strlen($plainTextMessage); $i++) {
    $codedMessage .= $plainTextMessage[$i] ^ $secretCharacter;
}
echo 'Coded Message is: '.$codedMessage.PHP_EOL;

$decodedMessage = '';
for($i = 0; $i < strlen($codedMessage); $i++) {
    $decodedMessage .= $codedMessage[$i] ^ $secretCharacter;
}

echo 'Decoded Message is: '.$decodedMessage.PHP_EOL;

答案 2 :(得分:1)

|是一个按位运算符 - 它不是对字符串或对象进行操作,而是对位(即0和1)进行操作。在这种情况下,|是OR。也就是说,设置第一个或第二个参数中的位。

当你将两者都表示为位时,取出共同的位,然后将其作为字符串回显,在这种情况下恰好为“{”。

是的,您可以使用它来编码事物 - 类似但更好的方法是使用XOR而不是OR。看看http://en.wikipedia.org/wiki/XOR_cipher

答案 3 :(得分:0)

这是按位“或”操作符。它返回由至少一个元素(1'1')中设置为'z'的位组成的结果。

以下所有结果都给出了相同的结果:

$r1 = '1' | 'z';
$r2 = chr(49) | chr(122); // chr(49) is '1', chr(122) is 'z'
$r3 = chr(49 | 122); // result is chr(123), which is '{'

并且所有这些都等于'{'。请参见此处的证据:http://ideone.com/YC048