web-dev-qa-db-fra.com

Quelles sont les chaînes intégrées de JavaScript?

cette question est difficile à résumer dans un titre de question

[~ # ~] mise à jour [~ # ~] J'ai créé un JSFiddle qui construit une chaîne obscurcie à partir de votre entrée en fonction des lettres extraites de cette question : Vous pouvez y accéder ici , ou un Gist serait-il plus facile?

Je suis récemment tombé sur un morceau amusant de JavaScript obscurci dans ce profil qui ressemble à ceci:

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]

Désolé de gâcher la surprise, mais lorsque cela est évalué, il renvoie ceci:

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

La façon dont cela fonctionne une fois éclaté, consiste à générer une série de messages et à en extraire des lettres comme cela (en utilisant le "je" comme exemple):

[]+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"

Les autres chaînes générées incluent:

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

Je voulais trouver un remplaçant pour le "n" et le "[" et j'ai trouvé ceci:

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

Ce que je ressens dans l'esprit d'utiliser les 1 et les 0, mais viole l'un des aspects les plus élégants du code original qui est l'apparence de n'avoir rien à voir avec les cordes. Quelqu'un d'autre a-t-il une idée de la façon de générer un "v" conforme au code obscurci d'origine?

Voici quelques informations supplémentaires qui ont été trouvées après que de nombreux programmeurs JavaScript talentueux aient approfondi cela

Firefox retourne "Je te suis seul" En raison de cette ligne:

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

[1^11<<1] coupe un caractère spécifique à partir de ceci:

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

Ce qui équivaut à ceci:

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

Qui ressemble à nous pourrions avoir notre "V" !!!

Chrome renvoie "Je t'aime", car le même code renvoie ceci:

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

Avant que la question ne soit fermée pour une connexion douteuse avec "un vrai problème de programmation", j'ai pensé ajouter une solution résumée qui s'appuie sur @ Supr's , @ Cory's et - @ alpha123's , voici:

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])

Compte tenu de la complexité du code et du message qu'il produit, c'est presque comme si le moteur JavaScript disait à quel point vous le ressentez :)

146
Jason Sperske

Tout d'abord, je voudrais remercier Jason et tous les contributeurs d'avoir joué avec cet extrait amusant. J'ai écrit ce morceau de code juste pour le plaisir afin de l'envoyer à ma femme le 14 février :) Ayant seulement Chrome installé sur l'ordinateur portable que j'avais) aucune option pour vérifier comment cela fonctionne dans Firefox et IE. De plus, je ne m'attendais pas vraiment à ce que la représentation toString() des méthodes intégrées puisse apparaître différemment dans d'autres navigateurs.

Maintenant, passer au vrai problème, regardons précisément le code. Oui, "v" Était le vrai "problème" ici. Je n'ai trouvé aucun autre moyen d'obtenir cette lettre, sauf l'analyse de la chaîne [native code], Qui peut être extraite de n'importe quelle méthode intégrée. Comme je me suis limité à ne pas avoir de chaînes et pas de nombres sauf 1 Utilisé, j'avais besoin d'exploiter une méthode qui n'a que des caractères disponibles dans son nom.

Les caractères disponibles peuvent être obtenus à partir des mots-clés existants et des représentations de chaînes, c'est-à-dire dès le début, nous avions NaN, null, undefined, Infinity, true, false et "[object Object]". Certains d'entre eux peuvent être facilement convertis en chaînes, par exemple 1/!1+[] Donne "Infinity".

J'ai analysé différentes méthodes intégrées pour les tableaux [], Les objets {}, Les expressions régulières /(?:)/, les nombres 1.1, Les chaînes "1" et découvert une belle méthode d'objet RegExp appelée test() . Son nom peut être assemblé à partir de tous les caractères disponibles, par ex. "t" Et "e" De true et "s" De false. J'ai créé une chaîne "test" Et j'ai traité cette méthode en utilisant la notation entre crochets pour le littéral regex /-/, Correctement identifié dans cette ligne:

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

Comme cela a déjà été discuté, ce morceau de code est évalué dans Chrome comme:

function test() { [native code] }

dans Firefox en tant que:

function test() {
    [native code]
}

et en IE as:

 function test() {     [native code] }  

(dans ce dernier payez spécial attention à l'espace avant function mot-clé)

Donc, comme vous le voyez clairement, mon code obtenait le 24ème caractère de la chaîne présentée, qui en Chrome était "v" (Comme prévu), mais malheureusement dans Firefox et = IE - "n" Et "[" Respectivement.

Afin de faire la même sortie dans tous les navigateurs, j'ai utilisé approche différente que celle illustrée dans les autres réponses. Maintenant, la version modifiée ressemble à ça:

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]

Cependant, afin d'intriguer les lecteurs, je ne fournirai pas de solution pour cela. Je crois honnêtement que vous comprendrez facilement comment cela fonctionne ... et certains peuvent même surprendre leur bien-aimé de manière multi-navigateur;)

P.S. Encore un autre obscurcisseur

Inspiré par l'idée de Jason de créer un outil d'obscurcissement universel, j'en ai écrit un de plus. Vous pouvez le trouver sur JSBin: http://jsbin.com/amecoq/2. Il peut masquer tout texte contenant des chiffres [0-9], Des petites lettres latines [a-z] Et des espaces. La longueur de la chaîne est principalement limitée à votre RAM (au moins le corps de ma réponse a été masqué avec succès). La sortie est prise en charge par Chrome, Firefox et IE.

Astuce: l'outil utilise une approche d'obfuscation différente de celle présentée ci-dessus.

83
VisioN

Pourquoi le native code peu de la question utilisée? Celui-ci donne un 'v' dans les deux Chrome et 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]

Modifier pour prendre en charge IE et le faire sans l'opérateur ternaire: Celui-ci fonctionne dans Chrome, IE et FF. Construit un tableau et utilise == pour déterminer le navigateur.

[([]+/-/[(!!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)]

Lisible:

[
    //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)
]
26
Supr

C'est à peu près aussi proche que possible, malheureusement, cela viole la convention de l'obscurcissement d'origine en appelant unescape():

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

Abattre:

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

Autres idées:

  1. Se rendre en quelque sorte à unescape("\x76")
  2. Convertissez en quelque sorte 118 Sans appeler String.fromCharCode()
  3. Obtenez le texte d'une exception avec le mot "non valide"

Mises à jour:

J'ai commencé à jouer au golf à code et je l'ai raccourci, en remplaçant les pièces par plus de 1, Etc.

8
Cᴏʀʏ

Pour le cas d'utilisation général, si la casse des caractères n'est pas un gros problème, je pourrais être enclin à tricher un peu.

Créez la fonction "c" qui transforme un nombre 0 .. 25 en caractère.

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]}}}};

Pour des raisons de performances, pré-cachez les lettres, si vous le souhaitez.

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

Dans la console Chrome, le tableau résultant ressemble à ceci:

> 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"]

Donc ... votre v pourrait être l[10+10+1].

Alternativement, une solution générale comme celle-ci:

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);

Ou, pour ce problème spécifique, peut-être juste:

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

Voici la partie qui génère le n/v:

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

Dans Firefox, ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]) évalue à

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

tandis que dans Chrome c'est

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

1^11<<1 est égal à 23. Donc, en raison de l'espace supplémentaire de Firefox, ce n'est pas tout à fait suffisant pour atteindre le "v", et c'est plutôt "n".

Et c'est pourquoi vous ne devriez pas vous fier au comportement de Function # toString. ;)

EDIT: Enfin, j'ai trouvé une version cross-browser raisonnablement obscurcie:

[[]+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]

Cela remplace la section n/v par:

([]+/-/[(!!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)]

qui exploite les différences dans parseInt (apparemment, Firefox analyse les nombres commençant par 0 comme octal, tandis que Chrome ne le fait pas) pour ajouter 4 dans le cas de Firefox, obtenant ainsi 'v' de 'native' dans les deux cas (Je ne trouve pas d'autre "v": P).
Le parseInt semble un peu déplacé, mais c'est le mieux que je puisse faire pour l'instant.

4
Peter C

Cela donne un v dans Chrome:

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

Et cela se fait dans Firefox:

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

Ils le retirent tous les deux de Object.prototype.preventExtensions(), donc vous pourriez probablement trouver un moyen multi-navigateur pour référencer cette méthode. (C'est le seul nom à 17 caractères dans Object.Prototype pour les débutants.)

N'hésitez pas à en construire une version plus obscure et à vous en attribuer le mérite, je n'ai plus de temps;)

3
Nathan Friedly

En chrome, l'expression ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]) Est évaluée à "function test() { [native code] }", [1^11<<1] Est évaluée à 23 (les opérateurs au niveau du bit entraînent la coupure de la variable à 32 bits)

2
enhzflep