Как преобразовать любую строку в битовую инвертированную строку ASCII?

В PHP вы можете использовать НЕ битовый оператор (~) для строк, например:

$ php -r "echo ~'šœ—ݶ';":^:lk<b=I

Как я могу конвертировать наоборот в допустимом диапазоне ASCII (0x80-0xFF)?

Другими словами, как найти инвертированную строку ASCII, которая будет генерировать строку, которую я хочу. При добавлении дополнительных ~ обычно он генерирует символы вне диапазона печати.

Например.

echo ~'HelloWorld';
??????????
echo ~~'HelloWorld';
HelloWorld
echo ~'lkbI'; // Despite of using the same characters as in the 1st example.
????

0

Решение

Теоретически, вы можете просто поместить данные, сгенерированные ~ обратно в код, ~ это снова, и восстановить исходную строку. На практике это работает не очень хорошо, потому что двоичные данные могут быть искажены промежуточной консолью и / или текстовым редактором, или контролем версий или программами FTP. Вы можете сделать двоичные данные безопасными, кодируя их некоторым способом, например, base 64:

echo base64_encode(~'HelloWorld');
t5qTk5CokI2Tmw==

echo ~base64_decode('t5qTk5CokI2Tmw==');
HelloWorld

Или вы можете записать необработанные двоичные данные, создав программный файл PHP:

file_put_contents('x.php', '<?php echo ~\'' . addcslashes(~'HelloWorld', '\\\'') . '\';');

При запуске сгенерированного файла будет правильно выведено «HelloWorld», хотя файл может быть поврежден, если какая-либо программа обработает его как текст.

2

Другие решения

Похоже, что вы хотите сделать, это инвертировать младшие 7 бит каждого символа, но оставить старший бит без изменений (так как он всегда должен быть нулем для ASCII).

Для отдельного байта вы можете сделать это с помощью XORing с 0x7f. Чтобы сделать это для всех байтов в строке, вам нужно создать строку одинаковой длины, все байты которой равны 0x7f. Так что-то вроде:

$a = "HelloWorld";
$b = $a ^ str_repeat("\x7f", strlen($a));

должно сработать.

2