Що таке вбудовані рядки JavaScript?


147

це питання важко підсумувати у назві запитання

ОНОВЛЕННЯ Я створив JSFiddle, який будує невмілий рядок із вашого введення на основі букв, витягнутих із цього питання: Ви можете отримати доступ до нього тут , чи суть буде простішою?

Нещодавно у цьому профілі я натрапив на прикольний затуманений JavaScript, який виглядає приблизно так:

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1
+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+([,][
~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+
1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

Вибачте, що зіпсував сюрприз, але коли це оцінюється, він повертає це:

"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10

Як це працює при розбитті, - це генерувати ряд повідомлень і витягувати з них букви так (використовуючи "Я" як приклад):

[]+1/!1
returns
"Infinity"
then
[[]+1/!1]
creates this array:
["Infinity"]
then
[[]+1/!1][1^1]
Takes the first (1^1 == 0) element of that array
"Infinity"
finally
[[]+1/!1][1^1][1>>1]
Takes the first (1>>1 == 0) char of that string
"I"

Інші рядки, що створюються, включають:

({}+[])       -> "[object Object]" (where the space comes from)
([]+!!-[])    -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[])  -> "undefined"

Мені було цікаво знайти заміну для "n" і "[" і придумав таке:

String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))

Я відчуваю себе в дусі використання значень "1" і "0", але порушує один з найелегантніших аспектів оригінального коду - зовнішній вигляд, що він взагалі не має нічого спільного з рядками. Хтось ще має уявлення про те, як генерувати "v", що відповідає оригінальному прихованому коду?

Ось додаткова інформація, яка була знайдена після того, як багато талановитих програмістів JavaScript більш глибоко розібралися в цьому

Firefox повертає "Я тебе закохав" Через цей рядок:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+

[1^11<<1] викреслює конкретного символу з цього:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])

Хто оцінює це:

"function test() {
    [native code]
}"

Як виглядає, ми можемо мати своє "V" !!!

Chrome повертає "Я тебе люблю", оскільки той самий код повертає це:

"function test() { [native code] }"

Перш ніж питання закрити для сумнівного зв’язку з "реальною проблемою програмування", я подумав би додати узагальнене рішення, яке ґрунтується на @ Supr's , @ Cory's і @ alpha123 , ось:

alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])

Зважаючи на складність коду та повідомлення, яке він створює, це майже так, як двигун JavaScript говорить про те, як ви особливо відчуваєте :)


9
На консолі Chrome воно говорить "любов". i.imgur.com/rVyKMoP.png
bfavaretto

2
Що робити, якщо ви знімете непотрібні літери з документа function test() { [native code] }, тоді ви могли б його нормалізувати та витягти потрібний лист
Jason Sperske

4
Наведення коду на нестандартному визначеному рядку для того, щоб надрукувати повідомлення з використанням затуманеного коду ... Я називаю це одним способом занадто локалізовано.

2
@Ian, правда. Якби люди в моєму житті, які я люблю, по-справжньому дбали про мене, вони користувалися б Chrome :)
Jason Sperske

4
Найкраще про це - це попередження, яке мій текстовий редактор дає: "Заплутане використання"! ""
Джейк Джонсон

Відповіді:


83

Перш за все, я хотів би подякувати Джейсону та всім учасникам, які грали з цим кумедним фрагментом. Я написав цей фрагмент коду просто для розваги , щоб надіслати його дружині 14 лютого :) Після встановлення лише Chrome на ноутбуці у мене не було можливості перевірити, як він працює в Firefox та IE. Більше того, я не дуже сподівався, що toString()представлення вбудованих методів може виглядати інакше в інших браузерах.

Тепер, переходячи до реальної проблеми , давайте точно розглянемо код. Так, тут "v"була справжня «проблема». Я не знайшов інших способів отримання цього листа, крім розбору [native code]рядка, який можна взяти з будь-якого вбудованого методу. Оскільки я обмежився тим, що не маю рядків і жодних цифр, крім 1використаних, мені потрібно було скористатися деяким методом, у своєму імені якого є лише доступні символи.

Доступні символи можуть бути отримані з існуючих ключових слів і рядків уявлень, тобто з самого початку ми мали NaN, null, undefined, Infinity, true, false, і "[object Object]". Деякі з них можна легко перетворити на рядки, наприклад, 1/!1+[]Give "Infinity".

Я проаналізував різні вбудовані методи для масивів [], об’єктів {}, регулярних виразів /(?:)/, чисел 1.1, рядків "1"та виявив один прекрасний метод, який RegExpназивається об'єктом test(). Його ім'я може бути зібрана з усіх доступних символів, наприклад , "t"і "e"з true, і "s"з false. Я створив рядок "test"і звернувся до цього методу, використовуючи позначення квадратних дужок для прямокутника регулярного виразів /-/, правильно визначеного в цьому рядку:

/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]

Як уже обговорювалося, цей фрагмент коду оцінюється в Chrome як:

function test() { [native code] }

в Firefox як:

function test() {
    [native code]
}

а в IE як:

 function test() {     [native code] }  

(в останньому зверніть особливу увагу на пробіл перед functionключовим словом)

Отже, як ви добре бачите, мій код отримував 24-й символ із представленого рядка, який у Chrome був "v"(як було заплановано), але, на жаль, у Firefox та IE - "n"і "["відповідно.

Для того, щоб зробити однаковий результат у всіх браузерах, я використовував інший підхід, ніж проілюстровано в інших відповідях. Тепер модифікована версія виглядає так:

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+/\[[^1]+\]/[([]+![])[1<<1<<
1]+(/|/[(1+{})[1+11>>>1]+[[]+{}][+!1][1]+([]+1/[])[1<<1>>1]
+([1<1]+[])[1+11>>>1+1]+[[!!1]+1][+[]][1-1]+([]+!!/!/)[1|1]
+(/1/[1]+[])[!1%1]+(-{}+{})[-1+1e1-1]+(1+[!!1])[1]+([]+1+{}
)[1<<1]+[!!/!!/+[]][+[]][1&1]]+/=/)[1e1+(1<<1|1)+(([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[1^1]==+!1)]+(!![]+{})[1|1<<1]+[1+{}+1][!1+!1][(11>>1)+1
]](([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+
(!!1+[])[1^1]]))[1&.1][11>>>1]+([,][~1]+[])[1-~1]+[[]+{}][!
1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[]
,[]+{}][1<<1>>>1][1||1]+(/[<+>]/[1&1|1]+[1.1])[1/11.1&1.11]

Однак, щоб заінтригувати читачів, я не надам рішення для цього. Я чесно вірю, що ви легко зрозумієте, як це працює ... і деякі можуть навіть здивувати коханого крос-браузерним способом;)

PS Ще один Obfuscator

Натхненний ідеєю Джейсона створити універсальний запаморочливий інструмент, я написав ще один. Ви можете знайти його на JSBin: http://jsbin.com/amecoq/2 . Він може заплутати будь-який текст, який містить цифри [0-9], маленькі латинські літери [a-z]та пробіли. Довжина рядка обмежена здебільшого вашою оперативною пам’яттю (принаймні частина моєї відповіді була успішно затуманена). Вихід підтримується Chrome, Firefox та IE.

Підказка: інструмент використовує інший підхід до обфускування, ніж був представлений вище.


4
"конструктор" ... дивовижно, і ви зберегли ідеальний прямокутник з дійсними розривами рядків. Ти хороший
Джейсон Сперські

1
Я створив Obfuscator, який створює рядок відповідно до ваших правил стилю: jsfiddle.net/w9rFF/8
Jason Sperske

@JasonSperske Це був приємний трюк! Чудова робота! Я спробую сприяти цьому.
VisioN

26

Чому не використовується native codeшматочок від запитання? Це дає як 'v'у Chrome, так і в Firefox:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]>([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]?([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]

Редагуйте, щоб підтримати IE і зробити це без потрійного оператора. Цей працює в Chrome, IE та FF. Створює масив і використовує ==для визначення браузера.

[([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]

Читає:

[
    //ie
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],
    //ch
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],
    //ff
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]
]
[
    //ch?
    ((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+
    //ff?
    ((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)
]

Це цікаво. Спочатку було визнано, що розміщення слів "рідний код" було непередбачуваним між Firefox та Chrome. Це вирішує це, але не працює в IE10 (де він повертає "i"). І все ж мені цікаво, чи може цей варіант запропонувати нові свіжі ідеї
Джейсон Сперський

Ідея полягає в тому , щоб просто вибрати як nі vі просто вибрати в залежності від того є найбільшим: str[23]>str[27]?str[23]:str[27]. Іншими словами, третій оператор - це фокус. Може бути також розширений, щоб підтримувати IE:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]
Supr

1
Ваша відповідь була спочатку (попереду творця оригінального коду), але я вважав, що його відповідь можна було б найбільш логічно вважати правильною. Ще велика робота (і заслужено 13 голосів)
Джейсон Сперський

1
Незначна нітпік: третинний оператор - третій за важливістю оператор, після первинного та вторинного. Оператор, який приймає три операнди, є потрійним.
Ерік Ліпперт

1
@EricLippert, га, я навіть погуглив це, щоб переконатися, що я використовую правильний термін, але все ж я все-таки закінчився неправильним! Спасибі, виправлено.
Супр

8

Це приблизно так близько, як я міг підійти, на жаль, це порушує конвенцію про початкове затуманення, закликаючи unescape():

unescape((/%/+[])[1]+(/1/[1]+[])[1%1]+(+!1)+(+!1)+(1e1+(11*(1-~1)<<1)))

Teardown:

(/%/+[])[1]          => "%"
(/1/[1]+[])[1%1]     => "u"
(+!1)                => "0"
(+!1)                => "0"
(1e1+(11*(1-~1)<<1)) => "76"
===========================
unescape("%u0076")   => "v"

Інші ідеї:

  1. Якось дістатися unescape("\x76")
  2. Якось конвертувати 118без дзвінківString.fromCharCode()
  3. Отримайте текст за винятком із написом слова "Недійсне"

Оновлення:

Я почав грати в гольф коду і скорочував його, замінюючи деталі на більше 1s і т.д.


Мені це також подобається. Я трохи розірваний у вибраній "правильній" відповіді, оскільки і ваш, і @ alpha123 виглядають надзвичайно заплутано і вміло приховують початковий намір.
Jason Sperske

І підтримка IE10 підписує угоду (із щирими вибаченнями @ alpha123 за відмінну відповідь)
Jason Sperske

Можна замінити , що '%'з (/%/+[[]+1/!1])[1]видаленням будь-яких цитат. Я також додав l=unescape;малі літери, Lщоб приховати посилання на unescape. Це було весело :)
Jason Sperske

@JasonSperske: Ще коротше:(/%/+[])[1]
1313

1
Або ви могли назвати свою змінну $1;
Cᴏʀʏ

4

Ось частина, яка генерує n / v:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]

У Firefox ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])оцінює до

"function test() {
    [native code]
}"

а в Chrome це

"function test() { [native code] }"

1^11<<1 дорівнює 23. Отже, через додатковий пробіл Firefox цього недостатньо, щоб дістатися до 'v', а натомість 'n'.

І саме тому вам не слід покладатися на функцію # toString. ;)

EDIT: Нарешті, я знайшов досить заплутану версію веб-переглядача:

[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]+([,][~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

Це замінює n / v розділ на:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]

який використовує відмінності в parseInt (мабуть, Firefox розбирає номери, починаючи з 0 у вісімці, а Chrome не), щоб додати 4 у випадку Firefox, таким чином отримуючи 'v' від 'native' в обох випадках (я не можу знайти іншого 'v ': Р).
Аналіз виглядає трохи поза місцем, але це найкраще, що я можу зробити зараз.


1
ПитанняDoes anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Ян

Дякую. Зараз я намагаюся розібратися в крос-браузерному способі зробити це ... "V" - це напрочуд незвичайне письмо ....
Пітер С

@Ian - ну тоді, мабуть, [(1 ^ 11 << 1) + 1 + 1 + 1 + 1] зробив би це?
enhzflep

@JanDvorak - У мене зараз немає ФФ. Що він оцінює? Якщо я можу бути настільки самонадійним, щоб запитати, тобто.
enhzflep

@enhzflep Вибачте, я мав на увазі "це не працюватиме в Chrome, з іншого боку"
Джон Дворак

4

У загальному випадку, якщо корпус символів не викликає особливих проблем, я, можливо, схильний трохи обдурити.

Створіть функцію "c", яка перетворює число 0 .. 25 в символ.

c=function(v){for(var i in window){for(var ci in i){if(parseInt(i[ci],(10+11+11)+(1<<1)+(1<<1))==(v+10)){return i[ci]}}}};

З міркувань продуктивності попередньо кешуйте листи, якщо хочете.

l=[];for(var i=0; i<(11+11)+(1<<1)+(1<<1);i++){l[i]=c(i);}

На консолі Chrome отриманий масив виглядає приблизно так:

> l;
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "K", "l", "m", "n", "o", "p", "q", "r", "S", "t", "u", "v", "w", "x", "y", "Z"]

Отже ... ваш v може бути l[10+10+1].

Як варіант, таке загальне рішення:

p=(function(){10%11}+[])[1+11+(1<<1)]; // "%"
u=(function(){club=1}+[])[1+11+(1<<1)]; // "u"
vc=p+u+(0+[])+(0+[])+((111>>1)+11+10+[]); // "%u0076"
unescape(vc);

Або для цієї конкретної проблеми, можливо, просто:

(function(){v=1}+[])[10+(1<<1)]; // "v"

3

Це дає av у Chrome:

Object.getOwnPropertyNames(Object)[17][3];

І це робиться в Firefox:

Object.getOwnPropertyNames(Object)[9][3]

Вони обидва витягують його з Object.prototype.preventExtensions(), так що, ймовірно, ви можете знайти крос-браузерний спосіб посилання на цей метод. (Це єдине 17-символьне ім'я в Object.Prototype для початківців.)

Не соромтеся створити більш затуманену версію цього і взяти всю кредит на себе, я не маю часу;)


2

У хромі вираження ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])оцінюється до "function test() { [native code] }", [1^11<<1]оцінюється до 23 (побітові оператори призводять до врізання змінної до 32 біт)


ПитанняDoes anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Ян
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.