JavaScriptの組み込み文字列とは何ですか?


147

この質問は、質問のタイトルに要約するのが難しい

UPDATE あなたがそれにアクセスすることができます。私はこの質問から抽出された文字をもとに、あなたの入力のうち難読化された文字列を構築します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

これが機能するときの動作方法は、一連のメッセージを生成し、そのようにして文字を引き出すことです(例として「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"

生成されるその他の文字列には、次のものがあります。

({}+[])       -> "[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を使用するという精神の中で感じていますが、文字列とはまったく関係がないように見える、元のコードのよりエレガントな側面の1つに違反しています。他の誰かが、元の難読化されたコードと一致する「v」を生成する方法についてのアイデアを持っていますか?

これは、才能のある多くのJavaScriptプログラマーがこれをさらに詳しく調べた後に見つかった追加情報です。

Firefoxは "I lone you"を返します。

([]+/-/[(!!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は「I love you」を返します。

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

「本当のプログラミングの問題」との疑わしい関係のために質問が締め切られる前に、@ Supr@ Cory、および@ 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
難読化されたコードを使用してメッセージを出力するために、標準に定義されていない文字列出力に基づいてコードを作成します...これはローカライズされた方法の 1つです。

2
@イアン、本当。私が大好きな私の人生の人々が本当に私を気にかけているなら、彼らはChromeを使うでしょう:)
Jason Sperske 2013

4
これについての最も良い部分は、私のテキストエディターが与える警告です:「 '!'の使用を混乱させる」
Jake Johnson

回答:


83

まず最初に、ジェイソンとその面白いスニペットで遊んでくれたすべての貢献者に感謝します。私は2月14日に妻に送信するために、楽しみのためにそのコードを書きました:)ラップトップにChromeのみがインストールされているため、FirefoxとIEでどのように機能するかを確認するオプションがありませんでした。さらに、私はそれを本当に期待していませんでしたtoString()メソッドの表現が他のブラウザーでは異なるように見えるを。

さて、本当の問題移りましょう。コードを正確に見てみましょう。はい、"v"本当の「問題」でした。[native code]文字列を解析する以外に、この文字を取得する他の方法は見つかりませんでした。文字列は、組み込みメソッドから取得できます。1使用する以外は文字列や数字を使用しないように制限していたため、名前に使用可能な文字のみが含まれるメソッドを利用する必要がありました。

使用可能な文字は、つまり私たちが持っていたスタートから、既存のキーワードや文字列表現から得ることができNaNnullundefinedInfinitytruefalse、と"[object Object]"。それらのいくつかは、容易例えば、文字列に変換することができます1/!1+[]提供します"Infinity"

配列[]、オブジェクト{}、正規表現/(?:)/、数値1.1、文字列のさまざまな組み込みメソッドを分析し"1"、とRegExp呼ばれる1つの美しいオブジェクトメソッドを発見しました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

だから、あなたがはっきり見えるように、私のコードは、Chromeでいた提示文字列から24文字になっていた"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 もう1つの難読化ツール

普遍的な難読化ツールを作成するというジェイソンのアイデアに触発されて、もう1つ書きました。JSBin:http ://jsbin.com/amecoq/2で見つけることができます。数字[0-9]、ラテン文字[a-z]、スペースを含むテキストを難読化できます。文字列の長さは、主にRAMによって制限されます(少なくとも、私の回答の本文は難読化されました)。出力はChrome、Firefox、IEでサポートされています。

ヒント:このツールは、上記で示したものとは異なる難読化アプローチを使用しています。


4
「コンストラクタ」...すごいです。有効な改行で完全な長方形を維持しました。あなたはいいです
ジェイソン・スパースケ2013

1
私はあなたのスタイルルールに従って文字列を作成する難読化ツール
Jason Sperske

@JasonSperskeそれはいいトリックでした!すごい仕事!それに貢献しようと思います。
VisioN 2013

26

native code質問のビットが使用されないのはなぜですか?これ'v'はChromeとFirefoxの両方でa を与えます:

([]+/-/[(!!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"を返します)。それでも、このオプションがいくつかの新鮮なアイデアを提供するかどうか疑問に思います
Jason Sperske 2013

アイデアは、両方nを選択し、vどちらか大きい方を選択することですstr[23]>str[27]?str[23]:str[27]。つまり、3次演算子がトリックです。IEもサポートするように拡張できます:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]
Supr

1
あなたの答えは最初(元のコードの作成者の前)でしたが、私は彼の答えが最も論理的に正しいものと考えられると感じました。それでも素晴らしい仕事(そしてそれにふさわしい13票)
Jason Sperske 2013

1
マイナーニティック:3次演算子は、1次および2次の次に重要な演算子です。3つのオペランドを取る演算子は三項です。
Eric Lippert 2013

1
@EricLippert、うーん、私はそれをググって正しい用語を使っていることを確認しましたが、それでも間違った用語になってしまいました!ありがとう、修正しました。
Supr

8

これは私が得ることができる限り近いですが、残念ながら、を呼び出すことにより、元の難読化の規約に違反していますunescape()

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

取り壊す:

(/%/+[])[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. 「無効」という単語を含む例外からテキストを取得する

アップデート:

私はコードゴルフを始め、それを短くしたり、パーツをより多く1のものに交換したりしています。


これも好きです。あなたと@ alpha123の両方が非常に難読化されており、元の意図を巧みに隠しているため、私は「正しい」答えを選択することに少し引き裂かれました。
Jason Sperske、2013

そしてIE10のサポートが契約を締めくくります(優れた回答について@ alpha123に心からお詫び申し上げます)
Jason Sperske 2013

引用符'%'(/%/+[[]+1/!1])[1]削除することでそれを置き換えることができます。l=unescape;小文字Lを使用してへの参照を非表示にすることも追加しましたunescape。これは楽しかったです:)
Jason Sperske 2013

@JasonSperske:さらに短く:(/%/+[])[1]
2013

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」です。

そして、これがFunction#toStringの動作に依存すべきではない理由です。;)

編集:最後に、私は合理的に難読化されたクロスブラウザバージョンを見つけました:

[[]+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から始まる数値を8進数として解析しますが、Chromeはそうではありません)、Firefoxの場合に4を追加します。したがって、どちらの場合も「ネイティブ」から「v」を取得します(別の「v ':P)。
parseIntは少し場違いに見えますが、今のところこれが最善の方法です。


1
問題はDoes anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Ian

ありがとう。今私はそれを行うためにクロスブラウザの方法を理解しようとしています... 'V'は驚くほど珍しい手紙です...
ピーターC

@イアン-それならおそらく、[(1 ^ 11 << 1)+ 1 + 1 + 1 + 1]はそれを行うでしょうか?
enhzflep 2013

@JanDvorak-現在FFはありません。それは何に評価されますか?私が尋ねるほどに大げさであるかもしれないならば、それはそうです。
enhzflep 2013

@enhzflep申し訳ありませんが、「一方で、Chromeでは機能しません」という意味でした
John Dvorak

4

以下のために、一般的な文字のケーシングは大きな問題ではない場合のユースケース、私は少しをごまかすために傾いている可能性があります。

数値0 .. 25を文字に変換する関数 "c"を作成します。

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

これはChromeでavを与えます:

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

そしてこれはFirefoxでそれをします:

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

それらは両方ともそれをから引き出しているObject.prototype.preventExtensions()ので、おそらくそのメソッドを参照するクロスブラウザーの方法を見つけることができるでしょう。(これはObject.Prototypeの最初の17文字の名前です。)

これをさらに難読化したバージョンを自由に作成して、自分の功績を信じてください。私は時間切れです;)


2

chromeでは、式はに([]+/-/[(!!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?
Ian
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.