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只能使用任何字符串,没有数字,只能使用数字,因此我需要开发一种名称中仅包含可用字符的方法。

可用字符可以从现有的关键字和字符串表示的获得,即开始我们有NaNnullundefinedInfinitytruefalse,和"[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.