Может кто-нибудь объяснить мне этот код PHP? Неожиданный результат из одной строки кода - PullRequest
0 голосов
/ 16 февраля 2012

Может кто-нибудь объяснить, что здесь делает PHP и возможно ли получить предсказуемый результат?

Может ли это быть использовано для сокрытия сообщений?

echo '1' | 'z';

Ответы [ 4 ]

2 голосов
/ 16 февраля 2012

Используется побитовый оператор ИЛИ

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

ИЛИ, получая два, дает

  00110001  1
| 01111010  z
= 01111011  {

, что составляет 0x7B, что является символом ASCII {

И, как было указаночтобы сделать это обратимым, вместо X ИЛИ

следует использовать XOR, а XOR дает два значения

  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 голосов
/ 16 февраля 2012

Если вы выполняете побитовую операцию между двумя строками, каждый символ в строке представляет октет из 8 битов.Затем побитовая операция выполняется символ за символом.Это означает, что сначала нужно преобразовать символ в целое число, например, с помощью функции ord, а затем преобразовать результат в строку (сравнимо с chr).

 echo '1' | 'z';

То же, что и

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

Взято из руководства по PHP:

Пример # 2 Побитовые операции XOR со строками

<?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 голос
/ 16 февраля 2012

| - побитовый оператор - вместо того, чтобы работать со строкой или объектом, он работает с битами (то есть с 0 и 1).В этом случае | - ИЛИ.То есть биты, которые находятся в первом или втором аргументе, установлены.

Когда вы представляете оба как биты, берете общие биты, а затем отображаете его как строку, это происходит как '{'в этом случае.

Да, вы можете использовать это для кодирования вещей - похожий, но лучший способ сделать это - использовать XOR вместо OR.Посмотрите на http://en.wikipedia.org/wiki/XOR_cipher.

0 голосов
/ 16 февраля 2012

Это побитовый оператор «или».Он возвращает результат, состоящий из битов, которые были установлены в 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

...