JavaScript的内置string是什么?
这个问题很难在题目中总结
更新我创build了一个JSFiddle,基于从这个问题中提取的字母,从input中生成一个模糊的string:你可以在这里访问它,或者一个要点会更容易吗?
我最近在这个configuration文件中遇到了一些模糊的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"
其他生成的string包括:
({}+[]) -> "[object Object]" (where the space comes from) ([]+!!-[]) -> "false" (used for it's "l") [/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o") (/<</[1]+[]) -> "undefined"
我有兴趣find替代“n”和“[”,并提出这个:
String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))
我觉得我本着使用1和0的精神,但是违反了原来代码中更优雅的一个方面,即与string无关的外观。 其他人有没有想法如何生成一个“V”,以保持原来的混淆代码?
这里有一些额外的信息是在许多有才华的JavaScript程序员深入研究之后发现的
火狐返回“我孤单你”由于这一行:
([]+/-/[(!!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] }"
在这个问题closures之前,由于“真正的编程问题”,我想我会添加一个基于@ Supr , @ Cory和@ alpha123的概括解决scheme。
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引擎告诉你有多特别:)
首先,我要感谢Jason和所有的贡献者玩这个有趣的片段。 我已经写了这段代码只是为了好玩 ,以便在2月14日发送给我的妻子:)只有Chrome安装在笔记本电脑上我没有select检查它是如何工作在Firefox和IE浏览器。 此外,我还没有真正地预料到,在其他浏览器中,内置方法的toString()
表示可能会有所不同。
现在, 转到真正的问题 ,让我们看看代码。 是的, "v"
是真正的“问题”在这里。 除了parsing[native code]
string,我发现没有其他的方式来获得这个字母,可以从任何内置的方法。 由于我限制自己没有string和除了1
使用的号码,我需要利用一些只有名字中可用字符的方法。
可用的字符可以从现有的关键字和string表示中获得,也就是从一开始我们有NaN
, null
, undefined
, Infinity
, true
, false
和"[object Object]"
。 其中一些可以很容易地转换为string,例如1/!1+[]
给出"Infinity"
。
我已经分析了数组[]
,对象{}
,正则expression式/(?:)/
,数字1.1
,string"1"
不同的内置方法,并且发现了一个名为test()
的RegExp
对象的一个漂亮的方法。 它的名字可以从所有可用的字符组合而来,例如"t"
和"e"
来自true
,而"s"
来自false
。 我已经创build了一个string"test"
并使用方括号标记正则expression式/-/
在本行中正确标识了这个方法:
/-/[(!!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
关键字前的空格)
所以,正如你清楚地看到的,我的代码是从显示的string中获得第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]
然而,为了吸引读者,我不会提供解决scheme。 我真的相信你会很容易理解它是如何工作的……有些甚至可以用浏览器的方式让他们心爱的人惊讶;)
PS 另一个混淆器
受Jason的想法的启发,我创build了一个通用的混淆工具,我又写了一个。 你可以在JSBinfind它: http : //jsbin.com/amecoq/2 。 它可以混淆包含数字[0-9]
,小拉丁字母[az]
和空格的任何文本。 string的长度主要受限于你的RAM(至less我的回答正文是成功混淆)。 Chrome,Firefox和IE支持输出。
提示:该工具使用了与上面介绍的不同的混淆方法。
为什么不是使用问题的native code
位? 这个在Chrome和Firefox中都给出了一个'v'
:
([]+/-/[(!!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。 build立一个数组,并使用==
来确定浏览器。
[([]+/-/[(!!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) ]
这跟我所能得到的差不多,不幸的是,它通过调用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"
其他想法:
- 以某种方式得到
unescape("\x76")
- 以某种方式转换
118
而不调用String.fromCharCode()
- 从exception中获取文本中的“无效”字样
更新:
我开始打高尔夫球,并且缩短了比赛时间,更换了更多的部分,等等。
以下是生成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]
这将replacen / 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中的差异(显然Firefoxparsing数字以0开头为八进制,而Chrome不)在Firefox的情况下添加4,从而在两种情况下从“native”获得“v”(我找不到另一个“v ':P)。
parseInt看起来有点不合适,但这是我现在可以做的最好的。
对于一般用例来说,如果angular色包装不是一个大问题,我可能会倾向于作弊一点。
创build函数“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]}}}};
出于性能原因,如果需要,请预先caching字母。
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]
。
或者,像这样的一般解决scheme:
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"
这在Chrome中提供了av:
Object.getOwnPropertyNames(Object)[17][3];
这在Firefox中是这样的:
Object.getOwnPropertyNames(Object)[9][3]
他们都把它从Object.prototype.preventExtensions()
,所以你可能find一个跨浏览器的方式来引用该方法。 (对于初学者,这是Object.Prototype中唯一的17个字符的名字。)
随意构build一个更加模糊的版本,并为自己所有的功劳,我没时间了;)
在chrome中,expression式([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
计算为"function test() { [native code] }"
, [1^11<<1]
评估为23(按位运算符导致variables被截断为32位)