Пользователь
0,0
рейтинг
8 января 2013 в 00:11

Разработка → Дело было вечером, echo «было нечего»

Добрый день хабр. В статье я расскажу, как используя синтаксис php, можно написать функцию для вывода переданной ей строковой переменной, не использующую в своем теле символы «a-zA-Z0-9<>?»

Вообще на хабре уже проскальзывали ссылки на статьи об использовании undefined variable, так что ничего нового я скорее всего не открою.


В php, как и в любом языке с динамической типизацией, есть моменты скрытые от конечного разработчика, на них мы и сыграем.

Начнем с конца. Мы всегда можем обратится к любому callable- была бы строка для вызова. Функции из SPL не исключение, хоть это и крайне редко применяется.
$v="print_r";
$v([1,2,3,4]);

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)

Но обратится таким способом ни к echo ни к print мы не можем, ибо они являются конструкциями языка, а не функциями. Можно было бы использовать printf например, но мне такой подход не понравился. Поэтому мы будем использовать для вывода функцию assert.
assert("print someShit");

Кстати заменить print на echo в выражении выше не выйдет, они оба не функции, но print хотя бы старается таковой казаться.

Строку для вывода нам передадут при вызове. Осталось самая малость. Получить строки «assert» и «print» используя доступный нам набор символов.

Для этого мы используем ряд особенностей языка.
1) В php мы можем обратится к undefined variable через _ (underscore). Нетрудно добится сужения типа и получить 0
var_dump(+_);

int(0)
2) При приведении массива к строке, он будет преобразован в строку со значением Array
//инициализируем пустой массив
$_[]++;
// В данном случае _ приводится к строке "_"
$_[]=$_._;
var_dump($_);

array(2) {
[0]=>
int(1)
[1]=>
string(6) "Array_"
}

3) Как и в большинстве других языков, строка фактически является массивом символов. Символы можно инкрементировать.

Скомбинировав все вышеперечисленное получаем такой код.

<?
error_reporting(E_ALL^E_NOTICE);
crazyOutput("было нечего");

function crazyOutput($__________){
$_[]++;
$_[]=$_._;
$_=$_[$_[+_]];
$___=$__=$_[++$__[]];
$____=$_=$_[+_];
$_++;$_++;$_++;
$_=$____.++$___.$___.++$_.$__.++$___;
$__=+_;$__=++$__+(++$__);
$____=$_[$__];
$____++;$____++;$____++;
$______=$____;
$____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;
$___=$____;
$____++;$____++;
$______++;
$___.=$____.$______;
$______++;$______++;$______++;$______++;$______++;
$___.=$______;
$__=+_;$__++;
$______=$___[$__];
$______++;$______++;
$___.=$______;
$_($___." '".$__________."'");
}
?>


/usr/bin/php /var/www/garbage/brainfuck.php
было нечего
Process finished with exit code 0


Практической пользы 0 в принципе… но что-то в этом есть =)

P.S Рекомендуется к прочтению
http://insert-script.blogspot.co.uk/2012/12/php-non-alpha-numeric-76-chars.html

http://www.thespanner.co.uk/2012/08/21/php-nonalpha-tutorial/
Дмитрий @sl4mmer
карма
10,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (21)

  • +32
    «Жениться тебе надо, барин» (с)

    А в общем затейно, мне понравилось.
    • +7
      Я женат =D
  • +4
    Было бы здорово, если бы без нотисов ;-)
  • +8
    Мои пять копеек

    <?
    error_reporting(E_ALL^E_NOTICE);
    crazyOutput("hello world");
    
    function crazyOutput($ы) {
        $ю = ~ЏЌ–‘‹™;
        $ю(~ЪЊ, $ы);
    }
    ?>
    


    Раскурите? :)

    Кодировка — cp1251
    • +3
      ~ЏЌ–‘‹™ = ~<8f><8d><96><91><8b><99>
      ~0x8f = 'p'
      ~0x8d = 'r'
      ~0x96 = 'i'
      ~0x91 = 'n'
      ~0x8b = 't'
      ~0x99 = 'f'

      ~ЪЊ = "%s"
  • +4
    /me ощутил отчётливый запах Brainfuck…
    UPD: упс, не заметил…
  • +1
    Вы сами это придумали? Очень похоже на www.thespanner.co.uk/2012/12/13/tweetable-php-non-alpha/
    • +1
      К сожалению я не так крут — первоначально прочитал эту статью. Оттуда уже перешел на указанный вами материал. собственно формирование assErt взял оттуда. Меня смущало присутствие символов в конечном коде =)
      • 0
        Но и Вы без кавычек не обошлись )
        • +1
          можно без кавычек запросто — call_user_func_array и printf, например. Только «брейнфака» с постинкрементами будет ОЧЕНЬ много :)
  • +8
    программа из одной строчки ни Perl
    помогите, пожалуйста исправить такую программу:

    cat «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'

    — не печатает

    anonymous (25.09.2003 8:46:28)

    www.linux.org.ru/forum/development/392747
    10 лет прошло почти
    • +1
      Ниже в треде: «потому что ты лох, потому и не печатает :) надо перед рекурсивным входом и удалением всех директорий один слеш убрать :) ЛОХ :)»

      И как я понял по треду, он прав!
      • 0
        UPD: не понял сразу — бред смолол
  • 0
    В php мы можем обратится к undefined variable через _ (underscore).

    А почему именно underscore? Поясните пожалуйста или дайте ссылку на соответствующий раздел в документации
    • +1
      Такое же имя переменной, как любое другое. Ничего особенного в _ нет, кроме экзотического вида. Любая переменная не определена, пока её не определят, и _ точно так же.
  • –1
    Практической пользы 0, стиль написания на высоте…
    • +3
      Тогда Вам не стоит заходить в записи из блога «Ненормальное программирование», там практичность не всегда преследуется авторами.
  • +2
    Новогодние праздники затянулись…
  • +1
  • 0
    А если набирать имена переменных через зажатый Alt + 0160, то получим «невидимый» символ. Он отображается как обычный пробел, но является разрешенным для именования переменных. Выходит можем писать такой вот головокружительный код:

    $  = 1;
    $  = 2;
    var_dump($  + $  );
    
    • 0
      в юникоде разных пробелов штук 10 наберется ;)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Интересные публикации