什么是 JavaScript 的内置字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15978204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 02:47:44  来源:igfitidea点击:

What are JavaScript's builtin strings?

javascriptobfuscation

提问by Jason Sperske

this question is difficult to summarize in a question title

这个问题很难用问题标题来概括

UPDATEI created a JSFiddle that builds an obfuscated string out of your input based on the letters extracted from this question: You can access it here, or would a gistbe easier?

更新我创建了一个 JSFiddle,它根据从这个问题中提取的字母从你的输入中构建一个混淆的字符串:你可以在这里访问它,或者一个要点会更容易吗?

I recently came across a fun bit of obfuscated JavaScript in this profilethat looks like this:

我最近在这个配置文件中发现了一个有趣的混淆 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]

Sorry to ruin the surprise but when this is evaluated it returns this:

很抱歉破坏了这个惊喜,但是当它被评估时,它会返回:

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

The way this works when broken out, is to generate a series of messages and to pull letters out of them like so (using the "I" as an example):

分解时的工作方式是生成一系列消息并像这样从中提取字母(以“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"

Other strings that are generated include:

生成的其他字符串包括:

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

I was interested in finding a replacement for the "n" and "[" and came up with this:

我有兴趣找到“n”和“[”的替代品,并想出了这个:

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

Which I feel in in the spirit of using 1's and 0's, but violates one of the more elegant aspects of the original code which is the appearance of having nothing to do with strings at all. Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?

本着使用 1 和 0 的精神,我感觉到了这一点,但违反了原始代码更优雅的方面之一,即外观与字符串完全无关。有没有其他人知道如何生成与原始混淆代码一致的“v”?

Here is some extra information that was found after many talented JavaScript programers took a deeper look at this

这是许多有才华的 JavaScript 程序员深入研究后发现的一些额外信息

Firefox returns "I lone you" Because of this line:

由于这一行,Firefox 返回“我孤独你”:

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

[1^11<<1]trims a specific character from this:

[1^11<<1]从中修剪一个特定的字符:

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

Which evaluates to this:

其评估为:

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

Which looks like we might have our "V"!!!

看起来我们可能有我们的“V”!!!

Chrome returns "I love you", because the same code returns this:

Chrome 返回“我爱你”,因为相同的代码返回:

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


Before the question is closed for questionable connection with "a real programming issue", I thought I'd add a summarized solution that builds on @Supr's, @Cory'sand @alpha123's, behold:

问题是关闭与“真正的编程问题”可疑连接之前,我想我会添加一个概括的解决方案,建立在@ SUPR的@科里@ 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])

Given the complexity of the code and the message it produces it's almost like the JavaScript engine is telling how special you make it feel :)

考虑到代码的复杂性和它产生的消息,它几乎就像 JavaScript 引擎在告诉你让它感觉有多特别:)

采纳答案by VisioN

First of all, I would like to thank Jason and all the contributors for playing with that funny snippet. I have written that piece of code just for funin order to send it to my wife on February 14 :) Having only Chrome installed on the laptop I had no options to check how it works in Firefox and IE. Moreover, I haven't really expected that toString()representation of build-in methods might look differently in other browsers.

首先,我要感谢 Jason 和所有贡献者玩这个有趣的片段。我写那段代码只是为了好玩,以便在 2 月 14 日将它发送给我的妻子 :) 在笔记本电脑上只安装了 Chrome 之后,我无法检查它在 Firefox 和 IE 中的工作方式。此外,我并没有真正预料到toString()内置方法的表示在其他浏览器中可能会有所不同。

Now, moving to the real problem, let's precisely have a look at the code. Yes, "v"was the real "problem" here. I found no other ways of getting this letter except parsing [native code]string, which can be taken from any built-in method. Since I limited myself with having no strings and no numbers except 1used, I needed to exploit some method that has only available characters in its name.

现在,转向真正的问题,让我们准确地看一下代码。是的,这里"v"才是真正的“问题”。我发现除了解析[native code]字符串之外没有其他方法可以获得这封信,可以从任何内置方法中获取。由于我限制自己没有字符串和数字,除了1使用之外,我需要利用一些名称中只有可用字符的方法。

Available characters can be obtained from existing keywords and string representations, i.e. from the start we had NaN, null, undefined, Infinity, true, false, and "[object Object]". Some of them can be easily converted to strings, e.g. 1/!1+[]gives "Infinity".

可用的字符可以从现有的关键字和字符串表示中获得,即从我们有NaN, null, undefined, Infinity, true, false, 和 开始"[object Object]"。其中一些可以轻松转换为字符串,例如1/!1+[]给出"Infinity"

I have analyzed different build-in methods for arrays [], objects {}, regular expressions /(?:)/, numbers 1.1, strings "1", and discovered one beautiful method of RegExpobject called test(). Its name can be assembled from all available characters, e.g. "t"and "e"from true, and "s"from false. I have created a string "test"and addressed this method using square brackets notation for regex literal /-/, correctly identified in this line:

我分析了数组[]、对象{}、正则表达式/(?:)/、数字1.1、字符串的不同内置方法"1",并发现了一种漂亮的RegExp对象方法,称为test(). 它的名称可以由所有可用字符组合而成,例如"t"and "e"fromtrue"s"from false。我创建了一个字符串"test"并使用方括号表示法处理了这个方法/-/,在这一行中正确标识了正则表达式文字:

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

As was already discussed, this piece of code is evaluated in Chrome as:

正如已经讨论过的,这段代码在 Chrome 中被评估为:

function test() { [native code] }

in Firefox as:

在 Firefox 中为:

function test() {
    [native code]
}

and in IE as:

在 IE 中为:

 function test() {     [native code] }  

(in the latter pay specialattention to the space before functionkeyword)

(在后者中要特别注意function关键字前的空格)

So, as you clearly see, my code was getting the 24th character from the presented string, which in Chrome was "v"(as was planned), but unfortunately in Firefox and IE -- "n"and "["respectively.

因此,正如您清楚地看到的那样,我的代码正在从显示的字符串中获取第 24 个字符,这在 Chrome 中是"v"(按计划),但不幸的是在 Firefox 和 IE 中——"n"以及"["分别。

In order to make the same output in all the browsers, I have used different approachthan illustrated in the other answers. Now the modified version looks like that:

为了在所有浏览器中产生相同的输出,我使用了与其他答案中所示不同的方法。现在修改后的版本是这样的:

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]

However, in order to intrigue the readers I won't provide a solution for that. I honestly believe that you will easily understand how it works... and some can even surprise their beloved in cross-browser way ;)

但是,为了引起读者的兴趣,我不会为此提供解决方案。老实说,我相信你会很容易理解它是如何工作的......有些甚至可以跨浏览器的方式让他们心爱的人大吃一惊;)

P.S. Yet Another Obfuscator

PS又一个混淆器

Inspired by Jason's idea to create a universal obfuscating tool, I have written one more. You can find it at JSBin: http://jsbin.com/amecoq/2. It can obfuscate any text that contains numbers [0-9], small latin letters [a-z], and spaces. The string length is limited mostly with your RAM (at least the body of my answer was successfully obfuscated). The output is supported by Chrome, Firefox, and IE.

受到 Jason 创建通用混淆工具的想法的启发,我又写了一个。您可以在JSBin 上找到它http: //jsbin.com/amecoq/2。它可以混淆任何包含数字[0-9]、小拉丁字母[a-z]和空格的文本。字符串长度主要受您的 RAM 限制(至少我的答案正文已成功混淆)。Chrome、Firefox 和 IE 支持输出。

Hint:the tool uses different obfuscation approach than was presented above.

提示:该工具使用与上述不同的混淆方法。

回答by Supr

Why isn't the native codebit from the question being used? This one gives a 'v'in both Chrome and Firefox:

为什么不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]


Edit to support IE and do it without the ternary operator:This one works in Chrome, IE, and FF. Builds an array and uses ==to determine browser.

编辑以支持 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)]

Readable:

可读:

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

回答by C???

This is about as close as I could get, unfortunately it violates the convention of the original obfuscation by making a call to unescape():

这几乎是我所能得到的,不幸的是,它通过调用以下方法违反了原始混淆的约定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"

Other ideas:

其他想法:

  1. Somehow get to unescape("\x76")
  2. Somehow convert 118without calling String.fromCharCode()
  3. Get the text from an exception with the word "Invalid" in it
  1. 以某种方式到达 unescape("\x76")
  2. 不知何故转换118而不调用String.fromCharCode()
  3. 从其中包含“无效”一词的异常中获取文本

Updates:

更新:

I started playing code golf and have been making it shorter, replacing parts with more 1s, etc.

我开始玩代码高尔夫,并一直在缩短它,用更多的1s替换零件,等等。

回答by svidgen

For the generaluse-case, if character casing isn't a big concern, I might be inclined to cheat a little.

对于一般用例,如果字符大小写不是一个大问题,我可能会倾向于作弊。

Create function "c" which turns a number 0 .. 25 into a character.

创建函数“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]}}}};

For performance reasons, pre-cache the letters, if you want.

出于性能原因,如果需要,可以预先缓存字母。

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

In the Chrome console, the resulting array looks like this:

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

So ... your vmight be l[10+10+1].

所以......你的v可能是l[10+10+1]

Alternatively, a general solution like this:

或者,像这样的通用解决方案:

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

Or, for this specificproblem, maybe just:

或者,对于这个特定问题,也许只是:

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

回答by Peter C

Here's the part that generates the n/v:

这是生成 n/v 的部分:

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

In Firefox, ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])evaluates to

在 Firefox 中,([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])评估为

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

while in Chrome it is

而在 Chrome 中它是

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

1^11<<1equals 23. So due to Firefox's extra whitespace, this isn't quite enough to get to the 'v', and is instead 'n'.

1^11<<1等于 23。因此,由于 Firefox 的额外空格,这还不足以到达“v”,而是“n”。

And this is why you shouldn't rely on Function#toString behavior. ;)

这就是为什么您不应该依赖 Function#toString 行为的原因。;)

EDIT: Finally I found a reasonably obfuscated cross-browser version:

编辑:最后我找到了一个合理混淆的跨浏览器版本:

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

This replaces the n/v section with:

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

which exploits differences in parseInt (apparently Firefox parses numbers starting with 0 as octal, while Chrome doesn't) to add 4 in Firefox's case, thus getting 'v' from 'native' in both cases (I can't find another 'v' :P).
The parseInt looks a little out of place, but that's the best I can do for now.

它利用了 parseInt 中的差异(显然 Firefox 将从 0 开始的数字解析为八进制,而 Chrome 没有)在 Firefox 的情况下添加 4,从而在两种情况下从 'native' 获得 'v'(我找不到另一个 'v ':P)。
parseInt 看起来有点不合适,但这是我现在能做的最好的。

回答by Nathan Friedly

This gives a v in Chrome:

这在 Chrome 中给出了 av:

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

And this does it in Firefox:

这在 Firefox 中做到了:

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

They both pull it out of Object.prototype.preventExtensions(), so you could probably find a cross-browser way to reference that method. (It's the only 17-character name in Object.Prototype for starters.)

它们都从 中提取出来Object.prototype.preventExtensions(),因此您可能会找到一种跨浏览器的方式来引用该方法。(对于初学者来说,这是 Object.Prototype 中唯一的 17 个字符的名称。)

Feel free to build a more-obfuscated version of this and take all the credit for yourself, I'm out of time ;)

随意构建一个更模糊的版本,并为自己赢得所有荣誉,我没时间了;)

回答by enhzflep

In chrome, the expression ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])evaluates to "function test() { [native code] }", the [1^11<<1]evaluates to 23 (bitwise operators cause the variable to be truncated to 32 bits)

在 chrome 中,表达式([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])计算为"function test() { [native code] }"[1^11<<1]计算为 23(按位运算符导致变量被截断为 32 位)