JavaScript压缩技术分析、实现

由于最近做的东西都是纯Javascript脚本的到网上下一些现成产品的代码,发现都有加密或混淆,因为很多加密其实是用Packer2的压缩实现的,就先讨论一下压缩吧,毕竟压缩后的代码至少可以让下载的速度快些吧。

目前JavaScript压缩的基本方法如下:
1、最常用的方法,将所有的注释去掉,然后将所有的回车去掉,最后把多余的空格也去掉。
2、高级点的方法,除了方法1的几个去除步骤外,加上了一个重命名变量的功能,把所有的变量名和方法名都变成由两三个字符组合的,达到进一步减肥的目的。
3、最后,用一些简单的压缩算法。

这里就不讨论方法1和方法2了。方法1过于简单;至于方法2,现在不少JavaScript代码保护软件的混淆就是这么做的,所以下次再探讨。

用与JavaScript的压缩算法和普通的压缩不同,不能使用太复杂的方法,毕竟解压的代码也是明码写在文件里的嘛。目前比较流行的是Packer2还有一个压缩效果很好的MemTronic's HTML JavaScript Cruncher-Compressor。个人认为Packer2的实现更好些,因为MemTronic's HTML JavaScript Cruncher-Compressor使用了ASCII码127之后的不可见字符,保存文件时弄错了编码,就前功尽弃。所以我们重点来讨论Packer2。

MemTronic's HTML JavaScript Cruncher-Compressor的实现我没有认真分析(代码好长,不是很想看),不过效果确实挺好的(不过你要是叫作者换成可见的字符,他就不一定有这个效果了),可惜保存到文件时比较麻烦,我复制到Microsoft Script Editor 7保存,有些字符就丢失了。用Unicode或者UTF8之类的编码保存,文件又会增大不少。

看到用不可见字符做分隔的方法,我之前也考虑用127之后的不可见字符来做个**进制,当初设想是当字典的索引成百上千后能省那么一点点,最后也是因为不可见字符的原因,放弃之。

Paker2的方法是首先用正则表达式将所有字符串取出,作为一个字典。然后将源代码中的字符串用字典中的索引来替换。最后在替换好的代码外加入一个Eval(……)的外壳,web页面在客户端运行时就能动态解压了。下面拿个具体的代码来看一下:

eval( function (p,a,c,k,e,d){e = function (c){ return (c < a ? "" :e(parseInt(c / a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace( / ^ / ,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('0(\'1\');',2,2,'alert|xxx'.split('|'),0,{}));
function(p,a,c,k,e,d)就是Packer2的标志。然后加入了一大堆的花指令,搞不懂作者想什么,压缩的东西还要弄得这么复杂。想看原来的代码也不需要什么特殊的工具,只要把最后的return p改为,document.getElementById(你的输出的目标).value = p就可以了。

我自己简化后的解压部分代码如下:
eval(( function  (e, d)
{
    e 
=  e.replace( new  RegExp( ' \\b\\w+\\b ' ' g ' ),  function  ($ 0 )
    {
        
return  d[$ 0 ];
    });
    
return  e;
}(
' 0(\ ' 1 \ ' ); ' ' alert|xxx ' .split( ' | ' ))));
简化一下实际就成了上面这个样子。可以很明了地看到,传入两个参数。参数e是经过替换后的代码,里面的数字对应字典里的位置。参数d对应的就是字典,为了节约,用“|”作分隔符和并成字符串。解压的原理也是一样,一个正则表达式的替换。

晕倒,居然忘了说压缩,还是如同上面的那个方法,在正则表达式替换的时候来个回调,先判断取得的字符串是否存在字典表里,如果不存在就增加,否则就取已存在的字符串的位置索引,然后把位置索引return回去让正则表达式自己做替换,重复n次,再然后,就OK啦。

放眼望去,现在不少东西是用Packer2的方法来做“加密”,连MapBar的最新版本的核心代码都是用Parcker2来压缩的,不过MapBar比较狠,还用JSOB之类的东西混淆了一回。挺流行的JQuery也是使用这种方法来做压缩的。


作者: 陈鹏(偶是坏人)
出处: http://cp800614.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

你可能感兴趣的:(JavaScript,html,加密,正则表达式,function,Microsoft)