JavaScript - это удивительный язык, который полон сюрпризов и хаоса, но тем не менее на нём держится вся веб-разработка, что делает его весьма популярным среди языков программирования. За последние несколько лет JS сильно изменился, вышла куча фреймворков, библиотек, а так же надстроек, которые сделали его неузнаваемым, но под капотом остаётся всё тот же причудливый язык, который напичкан странностями.
Например, верите ли вы, что с помощью одних только символов можно написать целую программу? Нет? Тогда приступим к извращению :)
Все примеры можно выполнить самому, даже не закрывая страницу. Просто достаточно открыть браузерную консоль и вписать туда строчки с кодом. Для этого необходимо нажать клавишу F12 и перейти в вкладку Console/Консоль - сверху или снизу будет поле для ввода кода.
Начнём с простого. Как думаете, что мы получим, выполнив следующий код?
!{}
Консоль нам выведет false. И мы уже можем получить 2 цифры - 0 и 1, просто выполнив следующее:
+!{} // получаем 0
+!!{} // получаем 1
Это, в принципе, даёт нам доступ к любым цифрам, нужно их только сложить между собой.
А если нам сделать так?
!{} + {}
Для тех, кто незнаком с JS, результат будет неожиданным, но это в порядке вещей. Мы получим строку:
false[object Object]
Получили строку, значит можем вытащить оттуда буквы. Сделать это можно с помощью массивов, обратившись к индексу буквы. Например, выполнив такой код, мы получим букву f
[!{} + {}][+!{}][ +!{} ]
Аналогично собираем всё остальное и сейчас у нас в запасе имеется f a l s e o b j c t
Для удобства, далее буквы я буду писать просто в виде букв, чтобы было читабельно, в конце выложу код из одних только символов!
Мы уже можем кое-что провернуть с полученными буквами, но оставим их на потом.
Получим новые буковки:
[][[]] + [] // строка undefined
Дополнив наш запас u n d i, мы почти можем собрать слово constructor, не хватает только r, которую заберём из следующей строки:
!!{} + {} // true[object Object]
Что ж, конструктор собран, и вот тут начинается самое веселье!
С помощью массива можно обратиться к любой функции или свойству объекта. Использовав constructor мы можем создать анонимную функцию, нужно лишь найти его в свойствах.
Например, из массива нам доступно много функций, которые мы можем получить, такие как fill, join, find и т.д. Они имеют конструктор, а значит помогут нам в решении задачи:
[]['join']['constructor'] // Function
Теперь можем делать что угодно в меру нашей фантазии и терпения!
Создаём нашу первую простую программу, вывод браузерного окна:
[]['join']['constructor'] ('alert("10")')();
В первых круглых скобках создаётся анонимная функция, вторыми скобками мы её вызываем и видим результат на экране!
Выглядит довольно просто, хотите взглянуть, как всё на самом деле?)
Наслаждайтесь!
[][((!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))*(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))-(+!!{})])+((!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+((+!!{})+(+!!{}))])+(([][[]]+[])[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+(+!!{})])+(([][[]]+[])[(+!!{})])][((!!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+(+!!{})])+((!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+((+!!{})+(+!!{}))])+(([][[]]+[])[(+!!{})])+((!{}+{})[((+!!{})+(+!!{}))+(+!!{})])+((!!{}+{})[+!{}])+((!!{}+{})[(+!!{})])+((!!{}+{})[((+!!{})+(+!!{}))])+((!!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+(+!!{})])+((!!{}+{})[+!{}])+((!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))+((+!!{})+(+!!{}))])+((!!{}+{})[(+!!{})])](((!{}+{})[(+!!{})])+((!{}+{})[((+!!{})+(+!!{}))])+((!{}+{})[(((+!!{})+(+!!{}))*((+!!{})+(+!!{})))])+((!!{}+{})[(+!!{})])+((!!{}+{})[+!{}])+'('+(+!!{})+''+(+!{})+')')();
Этот код выполняет то же самое, что и предыдущий, с одним лишь исключением - он написан с помощью символов.
Можете его легко проверить, выполнив в консоли браузера!
Разве это не прекрасно? Меня очень поражает гибкость и неоднозначность JavaScript'a, я его одновременно люблю и ненавижу. И это далеко не все его странности, есть ещё очень много вещей, о которых хочется рассказать.
Применение данному методу вряд ли где-то можно найти, разве что в шифровании кода, но на выходе он получится огромным. По сути, мы создали функцию из 11 символов и увеличили её в несколько раз.
Код выше я написал сам с нуля и не знаю, есть ли подобные генераторы.
А с какими странностями встречались вы?