Найти тему
Цифровой Алхимик

JavaScript извращения - программа на символах

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 символов и увеличили её в несколько раз.

Код выше я написал сам с нуля и не знаю, есть ли подобные генераторы.

А с какими странностями встречались вы?