我在js1k比赛中看到了一个演示,我对这种混淆算法感到惊讶。 有人可以解释它是如何工作的吗?我得到了混淆结果,但我无法理解其工作原理(混淆算法) 这是什么巫术? LOL
我已经提取了这个:
for(
encoded_string = '... encoded string ...';
g = /[^ -IM[-~]/.exec(encoded_string);
){
encoded_string = encoded_string.split(g).join(encoded_string.split(g).shift());
}
// ... Use encoded_string to do what you want
我认为可能重点在于REGEXP。
原始代码(http://js1k.com/2014-dragons/details/1854)
如果您愿意,可以在此处查看混淆的结果(http://jsbin.com/xeruqita/1/edit) 我添加了第一个var行。
答案 0 :(得分:1)
基本上,这个逻辑似乎从一个字符串中去掉一组字符的每个实例,并返回" clean"字符串。
我无法确定要移除的字符组(^ -IM[-~
)有什么特别之处,但我可以引导您完成他们正在做的事情。 。
设置for循环
for(
初始化循环变量
encoded_string = '... encoded string ...';
设置循环条件。 。 。注意:exec()
如果没有匹配则返回null
,而null
将评估为false
,结束循环
g = /[^ -IM[-~]/.exec(encoded_string);
结束循环条件
)
下一步有多个部分。 。 。让我逐步完成它
{
encoded_string = encoded_string.split(g).join(encoded_string.split(g).shift());
}
在每个循环中,获取exec(g
)的结果并将其用作分割原始encoded_string
的输入(这在两个地方完成)。
g
是一个数组,但是通过使用它作为split()
的输入,它被强制转换为字符串。这样做的结果是使用与字符串匹配的值(非常有趣,实际上,考虑到g
的构成......请参阅此处的规范:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec)。
将匹配用作"分离器"实际上,代码删除了该匹配的所有实例,并留下了所有" chunks"的数组。所有剩余字符的例子(例如:如果匹配为c
且字符串为abcde
,则拆分字符串将导致["ab", "de"]
)
然后使用split string两次:
它用作连接的源,用于创建结果字符串
那个"分裂数组的第一个元素"用作"加入字符"
所以,第二部分让我认为必须假设encoded_string
值必须始终以exec()
正则表达式模式中映射的一系列字符开头,因为如果是, "分裂数组的第一个字符"将永远是一个空白字符串,这意味着join()
的结果将是原始encoded_string
值,并删除所有匹配的字符。
如果这个假设不正确,那么" split array"的第一个位置会有一个实际的字符,并且该字符将被插入到分割数组中的所有元素之间,从而创建来自联接的非常不同的结果字符串。
让我举一些例子,以便更好地说明。 。
1)我的假设是正确的
这使用一个小输入字符串,以及与该字符串的第一个字符匹配的模式:
encoded_string = "abcdeabc";
g = /[abc]/.exec(encoded_string);
对于第一个循环,
g
会发现"a"
为第一场比赛,["", "bcde", "bc"]
,""
和join()
的结果为"bcdebc"
对于第二个循环,
g
会发现"b"
为第一场比赛,["", "cde", "c"]
,""
,join()
的结果为"cdec"
对于第三个循环,
g
会发现"c"
为第一场比赛,["", "de", ""]
,""
,join()
的结果为"de"
没有更多匹配,因此循环将以此结束,最终encoded string
值为"de"
。
2)我的假设不是
它使用与上面相同的输入字符串,但它使用不匹配该字符串的第一个字符的模式:
encoded_string = "abcdeabc";
g = /[bcd]/.exec(encoded_string);
对于第一个循环,
g
会发现"b"
为第一场比赛,["a", "cdea", "c"]
,"a"
,join()
的结果为"aacdeaac"
对于第二个循环,
g
会发现"c"
为第一场比赛,["aa", "deaa", ""]
,"aa"
,join()
的结果为"aaaadeaaaa"
对于第三个循环,
g
会发现"d"
为第一场比赛,["aaaa", "eaaaa"]
,"aaaa"
,join()
的结果为"aaaaaaaaeaaaa"
没有更多匹配,因此循环将以此结束,最终encoded string
值为"aaaaaaaaeaaaa"
。
虽然第二种方法可能可能是作者试图做的事情,但我的第一种方法是更有可能的功能。 ;)
唷!那是很多。希望有助于澄清!