pytanie to jest trudne do podsumowania w tytule pytania
AKTUALIZACJA Stworzyłem JSFiddle, który tworzy zaciemniony ciąg znaków z twoich danych wejściowych w oparciu o litery wyodrębnione z tego pytania: Możesz uzyskać do niego dostęp tutaj , czy może istota byłaby łatwiejsza?
Niedawno natknąłem się na zabawny kawałek zaciemnionego JavaScript w tym profilu, który wygląda tak:
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]
Przepraszam, że psuję niespodziankę, ale po ocenie zwraca to:
"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10
Sposób, w jaki to działa po rozbiciu, polega na wygenerowaniu serii wiadomości i wyciągnięciu z nich liter w ten sposób (na przykładzie „I”):
[]+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"
Inne generowane ciągi to:
({}+[]) -> "[object Object]" (where the space comes from)
([]+!!-[]) -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[]) -> "undefined"
Byłem zainteresowany znalezieniem zamiennika dla „n” i „[” i wymyśliłem to:
String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))
Który czuję w duchu używania jedynek i zer, ale narusza jeden z bardziej eleganckich aspektów oryginalnego kodu, którym jest pozory, że nie ma nic wspólnego ze stringami. Czy ktoś jeszcze ma pomysł, jak wygenerować „v”, które jest zgodne z oryginalnym zaciemnionym kodem?
Oto kilka dodatkowych informacji, które znaleziono po tym, jak wielu utalentowanych programistów JavaScript przyjrzało się temu dokładniej
Firefox zwraca „I lone you” Z powodu tego wiersza:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+
[1^11<<1]
wycina z tego określony znak:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
Który ocenia to:
"function test() {
[native code]
}"
Co wygląda na to, że możemy mieć nasze „V” !!!
Chrome zwraca „Kocham cię”, ponieważ ten sam kod zwraca to:
"function test() { [native code] }"
Zanim pytanie zostanie zamknięte z powodu wątpliwego połączenia z „prawdziwym problemem programistycznym”, pomyślałem, że dodam podsumowane rozwiązanie, które opiera się na @ Supr's , @ Cory's i @ alpha123's , oto:
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])
Biorąc pod uwagę złożoność kodu i generowanego przez niego komunikatu, jest to prawie tak, jakby silnik JavaScript mówił, jak wyjątkowo czujesz się w nim :)
źródło
function test() { [native code] }
Odpowiedzi:
Przede wszystkim chciałbym podziękować Jasonowi i wszystkim współpracownikom za zabawę z tym zabawnym fragmentem. Napisałem ten kod dla zabawy , aby 14 lutego wysłać go żonie :) Mając na laptopie tylko Chrome'a nie miałem możliwości sprawdzenia jak to działa w Firefoksie i IE. Co więcej, nie spodziewałem się, że
toString()
reprezentacja metod wbudowanych może wyglądać inaczej w innych przeglądarkach.Teraz przeniósł się do prawdziwego problemu , niech dokładnie przyjrzeć się kod. Tak,
"v"
był to prawdziwy „problem”. Nie znalazłem innych sposobów na uzyskanie tej litery, z wyjątkiem parsowania[native code]
ciągu, który można pobrać z dowolnej wbudowanej metody. Ponieważ ograniczyłem się do nie posiadania żadnych ciągów ani liczb poza1
używanymi, musiałem wykorzystać metodę, która ma tylko dostępne znaki w nazwie.Dostępne znaki mogą być uzyskane z istniejących słów kluczowych i reprezentacji ciąg, czyli od samego początku mieliśmy
NaN
,null
,undefined
,Infinity
,true
,false
, i"[object Object]"
. Część z nich można łatwo zamienić na stringi, np .1/!1+[]
Daje"Infinity"
.Przeanalizowałem różne wbudowane metody dla tablic
[]
, obiektów{}
, wyrażeń regularnych/(?:)/
, liczb1.1
, łańcuchów"1"
i odkryłem jedną piękną metodęRegExp
obiektu o nazwietest()
. Jego nazwa może być montowane ze wszystkich dostępnych znaków, na przykład"t"
i"e"
odtrue
i"s"
odfalse
. Utworzyłem ciąg"test"
i odniosłem się do tej metody, używając notacji w nawiasach kwadratowych dla literału wyrażenia regularnego/-/
, poprawnie zidentyfikowanego w tym wierszu:Jak już wspomniano, ten fragment kodu jest oceniany w Chrome jako:
w przeglądarce Firefox jako:
aw IE jako:
(w tym drugim przypadku należy zwrócić szczególną uwagę na miejsce przed
function
słowem kluczowym)Czyli jak widać, mój kod pobierał 24. znak z przedstawionego ciągu, który w Chrome był
"v"
(tak jak planowano), ale niestety w Firefoksie i IE -"n"
i"["
odpowiednio.Aby uzyskać taki sam wynik we wszystkich przeglądarkach, zastosowałem inne podejście niż pokazano w innych odpowiedziach. Teraz zmodyfikowana wersja wygląda tak:
Aby jednak zaintrygować czytelników, nie podam na to rozwiązania. Szczerze wierzę, że łatwo zrozumiesz, jak to działa ... a niektórzy potrafią nawet zaskoczyć ukochaną w cross-browser sposób;)
PS Jeszcze inny zaciemniacz
Zainspirowany pomysłem Jasona, aby stworzyć uniwersalne narzędzie zaciemniające, napisałem jeszcze jedno. Możesz go znaleźć na JSBin: http://jsbin.com/amecoq/2 . Może zaciemniać dowolny tekst zawierający cyfry
[0-9]
, małe litery łacińskie[a-z]
i spacje. Długość łańcucha jest ograniczona głównie przez pamięć RAM (przynajmniej treść mojej odpowiedzi została skutecznie zaciemniona). Dane wyjściowe są obsługiwane przez przeglądarki Chrome, Firefox i IE.Wskazówka: narzędzie korzysta z innego podejścia do zaciemniania niż zostało to przedstawione powyżej.
źródło
Dlaczego nie
native code
używa się fragmentu z pytania? Ten daje'v'
w obu Chrome i Firefox:Edytuj, aby obsługiwać IE i zrób to bez operatora trójargumentowego: ten działa w Chrome, IE i FF. Buduje tablicę i używa
==
do określenia przeglądarki.Czytelny:
źródło
n
av
i po prostu wybrać cokolwiek jest największy:str[23]>str[27]?str[23]:str[27]
. Innymi słowy, podstępem jest operator trzeciorzędny. Może zostać rozszerzony, aby obsługiwał również IE:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]
To jest tak blisko, jak tylko mogłem, niestety narusza konwencję oryginalnego zaciemniania, dzwoniąc pod numer
unescape()
:Zburzyć:
Inne pomysły:
unescape("\x76")
118
bez dzwonieniaString.fromCharCode()
Aktualizacje:
Zacząłem grać w code-golfa i skracałem go, wymieniając części na więcej
1
itd.źródło
'%'
przy(/%/+[[]+1/!1])[1]
usuwaniu żadnych cytatów. Dodałem równieżl=unescape;
użycie małych liter,L
aby ukryć odniesienie dounescape
. Było fajnie :)(/%/+[])[1]
$1
;Oto część, która generuje n / v:
W przeglądarce Firefox
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
ocenia jakopodczas gdy w Chrome jest
1^11<<1
równa się 23. Tak więc, ze względu na dodatkowe białe znaki Firefoksa, to nie wystarczy, aby dostać się do „v”, a zamiast tego jest „n”.I dlatego nie powinieneś polegać na zachowaniu Function # toString. ;)
EDYCJA: Wreszcie znalazłem rozsądnie zaciemnioną wersję dla różnych przeglądarek:
Spowoduje to zastąpienie sekcji n / v przez:
która wykorzystuje różnice w parseInt (najwyraźniej Firefox analizuje liczby zaczynające się od 0 jako ósemkowe, podczas gdy Chrome nie), aby dodać 4 w przypadku Firefoksa, uzyskując w ten sposób „v” z „natywnego” w obu przypadkach (nie mogę znaleźć innego „v ': P).
ParseInt wygląda trochę nie na miejscu, ale to najlepsze, co mogę teraz zrobić.
źródło
Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
W przypadku ogólnego zastosowania, jeśli wielkość liter nie jest dużym problemem, mogę być skłonny do trochę oszukiwania.
Utwórz funkcję „c”, która zamienia liczbę 0 ... 25 na znak.
Ze względu na wydajność, jeśli chcesz, wstępnie zapisz litery w pamięci podręcznej.
W konsoli Chrome wynikowa tablica wygląda następująco:
Więc ... Twoje v może być
l[10+10+1]
.Alternatywnie, ogólne rozwiązanie takie jak to:
Lub w przypadku tego konkretnego problemu może po prostu:
źródło
To daje av w Chrome:
I robi to w Firefoksie:
Obaj wyciągają to z
Object.prototype.preventExtensions()
, więc prawdopodobnie możesz znaleźć sposób na odwołanie się do tej metody w różnych przeglądarkach. (To jedyna 17-znakowa nazwa w Object.Prototype na początek.)Zapraszam do zbudowania bardziej zaciemnionej wersji tego i weź wszystko za siebie, nie mam czasu;)
źródło
W chrome, wyrażenie
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
szacuje się na"function test() { [native code] }"
,[1^11<<1]
zwraca 23 (operatory bitowe powodują obcięcie zmiennej do 32 bitów)źródło
Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?