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的精神感觉的,但是却违反了原始代码的一个更为优雅的方面,即与字符串完全无关的外观。还有其他人对如何生成与原始混淆代码保持一致的“ 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的,@科里和@ 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 13-4-12

4
将代码基于非标准定义的字符串输出,以便使用混淆后的代码打印消息...我称这种方法过于本地化。

2
@伊恩,是的。如果我一生中最爱的人关心我,他们会使用Chrome :)
— Jason Sperske

4
最好的部分是我的文本编辑器发出的警告:“混淆使用'!'”
— Jake Johnson

Answers:


83

首先,我要感谢Jason和所有贡献者使用这个有趣的摘录。我编写了这段代码只是为了好玩,以便于2月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"and和"e"from true和"s"from)组合而成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]

但是,为了吸引读者,我不会为此提供解决方案。老实说,我相信您会很容易理解它的工作原理,甚至有些人可能会以跨浏览器的方式惊讶于他们的挚爱;)

聚苯乙烯 另一个混淆器

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

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


4
“构造函数” ...哇,真是太神奇了,您保留了带有有效换行符的完美矩形。您很好
— Jason Sperske

1
我创建了一个混淆器,该混淆器创建了一个符合您的样式规则的字符串: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”)。仍然我不知道此选项是否可以提供一些新的想法
— Jason Sperske

想法是同时选择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)]
— 2013年

1
您的答案是第一个(原始代码的创建者之前),但是我认为从逻辑上讲他的答案可以被认为是正确的。仍然做得很好(当之无愧的13票赞成)
— Jason Sperske

1
次要操作:第三级操作员是仅次于第一级和第二级的第三大操作员。具有三个操作数的运算符是三元的。
— 埃里克·利珀特

1
@EricLippert,g,我什至在Google上搜索以确保我使用的是正确的术语,但最终还是输错了!谢谢,改正。
— 2013年

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. 从其中带有单词“ Invalid”的异常中获取文本

更新:

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


我也喜欢这个 在选择一个“正确”答案时,我有点被撕碎了,因为您和@ alpha123的外观都非常模糊并且巧妙地隐藏了最初的意图。
— 詹森·斯佩斯凯

IE10支持完成了交易(真诚的道歉@ alpha123是个很好的答案)
— Jason Sperske

您可以'%'通过(/%/+[[]+1/!1])[1]删除任何引号代替它。我还添加了l=unescape;使用小写字母L来隐藏对的引用unescape。这很有趣:)
— Jason Sperske

@JasonSperske:更短:(/%/+[])[1]
— Cᴏʀʏ

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开头的数字解析为八进制,而Chrome不会解析)在Firefox的情况下加4,因此在两种情况下都从'native'中获取'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”是一个出人意料的罕见字母....
— Peter C

@Ian-那么大概[[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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.