最近看到有些論壇在討論js壓縮、混淆和加密的問題,特地找了些資料看了下,如今總結一下:html
1.關於三者的定義與區別api
壓縮:刪除 Javascript 代碼中全部註釋、跳格符號、換行符號及無用的空格,從而壓縮 JS 文件大小,優化頁面加載速度。瀏覽器
混淆:通過編碼將變量和函數原命名改成毫無心義的命名(如function(a,b,c,e,g)等),以防止他人窺視和竊取 Javascript 源代碼,也有必定壓縮效果。ide
加密:通常用eval方法加密,效果與混淆類似,也作到了壓縮的效果。函數
從定義中能夠看出,壓縮的主要目的是消除註釋等無用字符,達到精簡js代碼,減少js文件大小的目的,這也是頁面優化的一種方式;而混淆和加密的目的比較接近,都是爲了防止他人直接查看源碼,對代碼(如重要的api等)起保護做用,但這也只是增長了閱讀代碼的代價,也就是所謂的防君子不防小人。可是當混淆和加密聯合使用時,如先混淆在加密(或者先加密再混淆)時,破解時間就會增長。關於js的加密,能夠參考這篇文章:http://www.cnblogs.com/top5/archive/2009/08/07/1540860.html工具
2.demo優化
下面以更直觀的方式來體會一下這四種方式(壓縮、混淆、加密、混淆&加密)的不一樣。this
源js代碼以下:編碼
1 /* 這個是一個類 */ 2 3 function xx(num, str) { 4 //說明 5 var a = num; 6 this.aa = a; 7 this.bb = function() {alert(str);} 8 this.cc = function() { 9 for (var i = 0; i < 10; i++) { 10 document.title = i; 11 } 12 } 13 this.yy = new yy(); 14 function xxf() { 15 alert("xxf"); 16 if ((/\{\d+\}/).test("a\sdf{2}ab")) 17 alert("{\\d} is match!"); 18 } 19 } 20 xx.prototype.dd = function(){ 21 alert("dd"); 22 a.yy.ll(); 23 var fnx = function(i) { 24 this.ab = i; 25 this.aa = function(){ 26 alert(this.ab); 27 } 28 } 29 var f1 = new fnx(1); 30 f1.aa(); 31 } 32 33 function yy(){ 34 alert('yy'); 35 } 36 yy.prototype.ll = function() { 37 alert("yyll"); 38 } 39 40 var a = new xx(100, "hello"), b = new xx(0, "ttyp"); 41 eval("a.aa=20"); 42 a.bb(); 43 b.dd(); 44 alert(a.aa); 45 46 var k = 9; 47 function kk() { 48 var k = 0; 49 alert(k); 50 } 51 kk(); 52 alert(k); 53 //輸入結果alert:"yy"->"yy"->"hello"->"dd"->"yyll"->"12"->"20"->"0"->"9"
(1)通過壓縮後的代碼以下:加密
1 function xx(num,str){var a=num;this.aa=a;this.bb=function(){alert(str)};this.cc=function(){for(var i=0;i<10;i++){document.title=i}};this.yy=new yy();function xxf(){alert("xxf");if((/\{\d+\}/).test("a\sdf{2}ab"))alert("{\\d} is match!")}};xx.prototype.dd=function(){alert("dd");a.yy.ll();var fnx=function(i){this.ab=i;this.aa=function(){alert(this.ab)}};var f1=new fnx(1);f1.aa()};function yy(){alert('yy')};yy.prototype.ll=function(){alert("yyll")};var a=new xx(100,"hello"),b=new xx(0,"ttyp");eval("a.aa=20");a.bb();b.dd();alert(a.aa);var k=9;function kk(){var k=0;alert(k)};kk();alert(k);
壓縮後與源碼相比只是少了註釋、空格、換行等。
(2)通過混淆後的代碼以下:
1 function xx(d,e){var f=d;this.aa=f;this.bb=function(){alert(e)};this.cc=function(){for(var g=0;g<10;g++){document.title=g}};this.yy=new yy();function xxf(){alert("xxf");if((/\{\d+\}/).test("a\sdf{2}ab"))alert("{\\d} is match!")}};xx.prototype.dd=function(){alert("dd");a.yy.ll();var fnx=function(e){this.ab=e;this.aa=function(){alert(this.ab)}};var d=new fnx(1);d.aa()};function yy(){alert('yy')};yy.prototype.ll=function(){alert("yyll")};var a=new xx(100,"hello"),b=new xx(0,"ttyp");eval("a.aa=20");a.bb();b.dd();alert(a.aa);var c=9;function kk(){var d=0;alert(d)};kk();alert(c);
混淆後除了少了註釋、空格和換行等,參數也被a,b,c,d,e等字符代替,提升了閱讀的難度。
(3)通過加密後的代碼以下:
1 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;}('3 e(o,l){5 a=o;6.8=a;6.p=3(){4(l)};6.B=3(){A(5 i=0;i<y;i++){x.z=i}};6.7=c 7();3 j(){4("j");t((/\\{\\d+\\}/).s("a\\u{2}g"))4("{\\\\d} w v!")}};e.r.f=3(){4("f");a.7.h();5 n=3(i){6.g=i;6.8=3(){4(6.g)}};5 m=c n(1);m.8()};3 7(){4(\'7\')};7.r.h=3(){4("D")};5 a=c e(F,"H"),b=c e(0,"G");E("a.8=C");a.p();b.f();4(a.8);5 k=9;3 q(){5 k=0;4(k)};q();4(k);',44,44,'|||function|alert|var|this|yy|aa||||new||xx|dd|ab|ll||xxf||str|f1|fnx|num|bb|kk|prototype|test|if|sdf|match|is|document|10|title|for|cc|20|yyll|eval|100|ttyp|hello'.split('|'),0,{}))
加密後除了有混淆的做用外,有些代碼被加密了,進一步提升了閱讀的難度。
(4)通過混淆&加密後的代碼以下
1 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;}('4 i(d,e){5 f=d;6.8=f;6.p=4(){3(e)};6.s=4(){t(5 g=0;g<y;g++){G.F=g}};6.7=h 7();4 l(){3("l");x((/\\{\\d+\\}/).v("a\\u{2}j"))3("{\\\\d} w r!")}};i.o.k=4(){3("k");a.7.m();5 n=4(e){6.j=e;6.8=4(){3(6.j)}};5 d=h n(1);d.8()};4 7(){3(\'7\')};7.o.m=4(){3("E")};5 a=h i(A,"z"),b=h i(0,"B");D("a.8=C");a.p();b.k();3(a.8);5 c=9;4 q(){5 d=0;3(d)};q();3(c);',43,43,'|||alert|function|var|this|yy|aa|||||||||new|xx|ab|dd|xxf|ll|fnx|prototype|bb|kk|match|cc|for|sdf|test|is|if|10|hello|100|ttyp|20|eval|yyll|title|document'.split('|'),0,{}))
3.瀏覽器是怎麼解析混淆和加密後的js代碼的
4.js壓縮工具
其實js的壓縮工具網上有不少,在線和安裝版的都有,文章中使用的是HDS JSObfuscator v2.13綠色版。
在線的js壓縮工具:http://tool.chinaz.com/js.aspx
5.注意事項
源js文件必定要按照規範編寫,分號,註釋符,var等都要規範,不然很容易出錯。
6.參考文章
(1)http://m.blog.csdn.net/blog/Shb_derek/25032169