CLASS_CONFUSION JS混淆 全源碼
更新時間:2007年12月12日 21:14:24 投稿:mdxy-dxy
這里通過JS字符串替換、隨機(jī)數(shù)運(yùn)算實(shí)現(xiàn)混淆JS代碼,達(dá)到降低代碼可讀性,以保護(hù)代碼的目的,需要的朋友可以參考一下
利用隨機(jī)字符串代替變量等,混淆原代碼,保護(hù)自己寫的代碼,不利于別人直接剽竊
復(fù)制代碼 代碼如下:
<SCRIPT language=JavaScript>
<!--
/**//**//**//**
**
==============================================================
====================================
** 類名:CLASS_CONFUSION
** 功能:JS混淆
** 示例:
---------------------------------------------------------
------------------------------------------
var xx = new CLASS_CONFUSION(code);
document.getElementById("display").innerHTML =
xx.confusion();
---------------------------------------------------------
------------------------------------------
** 作者:ttyp
** 郵件:ttyp@21cn.com
** 日期:2006-3-20
** 版本:0.12
**
==============================================================
====================================
**/
function CLASS_CONFUSION(code){
//哈希表類
function Hashtable(){
this._hash = new Object();
this.add = function(key,value){
if(typeof(key)!="undefined"){
if(this.contains(key)==false){
this._hash[key]=typeof
(value)=="undefined"?null:value;
return true;
} else {
return false;
}
} else {
return false;
}
}
this.remove = function(key){delete this._hash
[key];}
this.count = function(){var i=0;for(var k in
this._hash){i++;} return i;}
this.items = function(key){return this._hash
[key];}
this.contains = function(key){return typeof
(this._hash[key])!="undefined";}
this.clear = function(){for(var k in
this._hash){delete this._hash[k];}}
}
function VariableMap(parent){
this.table = new Hashtable();
this.level = parent?parent.level+1:0;
this.parent= parent;
this.add = function(key,value){this.table.add
(key,value)};
this.items = function(key){return this.table.items
(key)};
this.count = function(){return this.table.count()};
this.contains = function(key){return
this.table.contains(key);}
this.isParameter = false;
}
this._caseSensitive = true;
//字符串轉(zhuǎn)換為哈希表
this.str2hashtable = function(key,cs){
var _key = key.split(/,/g);
var _hash = new Hashtable();
var _cs = true;
if(typeof(cs)=="undefined"||cs==null){
_cs = this._caseSensitive;
} else {
_cs = cs;
}
for(var i in _key){
if(_cs){
_hash.add(_key[i]);
} else {
_hash.add((_key[i]+"").toLowerCase());
}
}
return _hash;
}
//獲得需要轉(zhuǎn)換的代碼
this._codetxt = code;
if(typeof(syntax)=="undefined"){
syntax = "";
}
this._deleteComment = false;
//是否大小寫敏感
this._caseSensitive = true;
//得到關(guān)鍵字哈希表
this._keywords = this.str2hashtable
("switch,case,delete,default,typeof,for,in,function,void,this,
boolean,while,if,return,new,true,false,try,catch,throw,null,el
se,do,var");
this._function = this.str2hashtable("function");
this._var = "var";
this._beginBlock = "{";
this._endBlock = "}";
this._window = this.str2hashtable
("alert,escape,unescape,document,parseInt,parseFloat");
//得到內(nèi)建對象哈希表
this._commonObjects = this.str2hashtable
("String,Number,Boolean,RegExp,Error,Math,Date,Object,Array,Gl
obal");
//得到分割字符
this._wordDelimiters= " ,.?!;:\\/<>(){}[]\"'\r\n\t=+-
|*%@#$^&";
//引用字符
this._quotation = this.str2hashtable("\",'");
//行注釋字符
this._lineComment = "http://";
//轉(zhuǎn)義字符
this._escape = "\\";
//多行引用開始
this._commentOn = "/*";
//多行引用結(jié)束
this._commentOff = "*/";
this._execute = "eval";
//引用調(diào)用字符
this._call = ".";
this._varPause = "=";
this._varContinue = ",";
//變量個數(shù)
this._varNum = 0;
this.confusion = function() {
var codeArr = new Array();
var word_index = 0;
var htmlTxt = new Array();
//得到分割字符數(shù)組(分詞)
for (var i = 0; i < this._codetxt.length; i++) {
if (this._wordDelimiters.indexOf
(this._codetxt.charAt(i)) == -1) { //找不到關(guān)鍵字
if (codeArr[word_index] == null || typeof
(codeArr[word_index]) == 'undefined') {
codeArr[word_index] = "";
}
codeArr[word_index] += this._codetxt.charAt
(i);
} else {
if (typeof(codeArr[word_index]) != 'undefined'
&& codeArr[word_index].length > 0)
word_index++;
codeArr[word_index++] = this._codetxt.charAt
(i);
}
}
var quote_opened = false; //引用標(biāo)記
var slash_star_comment_opened = false; //多行注
釋標(biāo)記
var slash_slash_comment_opened = false; //單行注
釋標(biāo)記
var line_num = 1; //行號
var quote_char = ""; //引用
標(biāo)記類型
var call_opened = false;
var call_string = "";
var var_opened = false;
var var_pause = false;
var function_opened = false;
var parameter_opened = false;
var var_map = new VariableMap
();
var cur_var_map = var_map;
var execute_opened = false;
//按分割字,分塊顯示
for (var i=0; i <=word_index; i++){
//單獨(dú)處理指針引用
if(call_opened&&typeof(codeArr[i])!="undefined"){
if(call_string.length==0){
if(this.isVar(codeArr[i])){
call_string +=codeArr[i];
}else{
htmlTxt[htmlTxt.length] = "[\"" +
this.toHex(call_string) + "\"]";
if(codeArr[i]!=this._call){
htmlTxt[htmlTxt.length] = codeArr
[i];
call_opened = false;
}
call_string = "";
}
} else {
if(!this.isVar(codeArr[i])){
htmlTxt[htmlTxt.length] = "[\"" +
this.toHex(call_string) + "\"]";
if(codeArr[i]!=this._call){
htmlTxt[htmlTxt.length] = codeArr
[i];
call_opened = false;
}
call_string = "";
}else{
htmlTxt[htmlTxt.length] = "[\"" +
this.toHex(call_string) + "\"]";
}
}
continue;
}
//處理空行(由于轉(zhuǎn)義帶來)
if(typeof(codeArr[i])=="undefined"||codeArr
[i].length==0){
continue;
} else if(codeArr[i]==" "){
htmlTxt[htmlTxt.length] = " ";
} else if(codeArr[i]=="\n"){
//處理換行
} else if (codeArr[i] == "\r"){
slash_slash_comment_opened = false;
quote_opened = false;
var_opened = false;
htmlTxt[htmlTxt.length] = "\r\n";
line_num++;
//處理function里的參數(shù)標(biāo)記
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&this.isFunction
(codeArr[i])){
htmlTxt[htmlTxt.length] = codeArr[i];
function_opened = true;
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]=="("){
htmlTxt[htmlTxt.length] = codeArr[i];
if(function_opened == true){
function_opened =false;
var_opened = true;
cur_var_map = new VariableMap
(cur_var_map);
cur_var_map.isParameter = true;
}
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]==")"){
htmlTxt[htmlTxt.length] = codeArr[i];
//處理var a = new Class(),b=new Date();類似的
問題
if(cur_var_map.isParameter){
var_opened = false;
var_pause = false;
}
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]==";"){
htmlTxt[htmlTxt.length] = codeArr[i];
var_opened = false;
var_pause = false;
if(execute_opened){
execute_opened = false;
}
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]
==this._var){
htmlTxt[htmlTxt.length] = codeArr[i];
var_opened = true;
var_pause = false;
} else if(!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]
==this._varPause){
htmlTxt[htmlTxt.length] = codeArr[i];
var_pause = true;
} else if(!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]
==this._varContinue){
htmlTxt[htmlTxt.length] = codeArr[i];
var_pause = false;
} else if(!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]
==this._beginBlock){
cur_var_map = new VariableMap(cur_var_map);
var_opened = false;
htmlTxt[htmlTxt.length] = codeArr[i];
} else if(!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]
==this._endBlock){
cur_var_map = cur_var_map.parent;
if(cur_var_map.isParameter){
cur_var_map = cur_var_map.parent;
}
htmlTxt[htmlTxt.length] = codeArr[i];
//處理引用調(diào)用
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&codeArr[i]
==this._call){
//判斷引用(.)后面第一個是否為字母貨_$
if(i<word_index-1){
if(this.isVar(codeArr[i+1])){
if(call_opened){
htmlTxt[htmlTxt.length] =
this.toHex(call_string);
}
call_opened = true;
}else{
htmlTxt[htmlTxt.length] = this._call;
}
}else{
htmlTxt[htmlTxt.length] = this._call;
}
//處理關(guān)鍵字
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened && this.isKeyword
(codeArr[i])){
htmlTxt[htmlTxt.length] = codeArr[i];
//處理eval后的字符串
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened && codeArr[i]
==this._execute){
htmlTxt[htmlTxt.length] = "window[\"" +
this.toHex(codeArr[i]) + "\"]";
execute_opened = true;
//window內(nèi)置對象
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened && this.isWindow
(codeArr[i])){
htmlTxt[htmlTxt.length] = "window[\"" +
this.toHex(codeArr[i]) + "\"]";
//處理普通對象
} else if (!slash_slash_comment_opened&&!
slash_star_comment_opened && !quote_opened &&
this.isCommonObject(codeArr[i])){
htmlTxt[htmlTxt.length] = "window[\"" +
this.toHex(codeArr[i]) + "\"]";
//處理雙引號(引號前不能為轉(zhuǎn)義字符)
} else if (!slash_star_comment_opened&&!
slash_slash_comment_opened&&this._quotation.contains(codeArr
[i])){
if (quote_opened){
//是相應(yīng)的引號
if(quote_char==codeArr[i]){
htmlTxt[htmlTxt.length] = codeArr[i];
quote_opened = false;
quote_char = "";
} else {
htmlTxt[htmlTxt.length] = this.toHex
(codeArr[i]);
}
} else {
htmlTxt[htmlTxt.length] = codeArr[i];
quote_opened = true;
quote_char = codeArr[i];
}
//處理轉(zhuǎn)義字符
} else if(codeArr[i] == this._escape){
htmlTxt[htmlTxt.length] = codeArr[i];
if(i<word_index-1){
if(codeArr[i+1].charCodeAt(0)
>=32&&codeArr[i+1].charCodeAt(0)<=127){
htmlTxt[htmlTxt.length] = codeArr
[i+1].substr(0,1);
htmlTxt[htmlTxt.length] = this.toHex
(codeArr[i+1].substr(1));
i=i+1;
}
}
//處理多行注釋的開始
} else if (!slash_slash_comment_opened && !
slash_star_comment_opened&&!quote_opened&&this.isStartWith
(this._commentOn,codeArr,i)){
slash_star_comment_opened = true;
htmlTxt[htmlTxt.length] = this._commentOn;
i = i + this.getSkipLength(this._commentOn);
//處理單行注釋
} else if (!slash_slash_comment_opened && !
slash_star_comment_opened&&!quote_opened&&this.isStartWith
(this._lineComment,codeArr,i)){
slash_slash_comment_opened = true;
if(!this._deleteComment){
htmlTxt[htmlTxt.length] =
this._lineComment;
}
i = i + this.getSkipLength(this._lineComment);
//處理忽略詞
} else if (!slash_slash_comment_opened && !
slash_star_comment_opened&&!quote_opened&&this.isStartWith
(this._ignore,codeArr,i)){
slash_slash_comment_opened = true;
htmlTxt[htmlTxt.length] = this._ignore;
i = i + this.getSkipLength(this._ignore);
//處理多行注釋結(jié)束
} else if (!quote_opened&&!
slash_slash_comment_opened&&this.isStartWith
(this._commentOff,codeArr,i)){
if (slash_star_comment_opened) {
slash_star_comment_opened = false;
if(!this._deleteComment){
htmlTxt[htmlTxt.length] =
this._commentOff;
}
i = i + this.getSkipLength
(this._commentOff);
}
} else {
//不是在字符串中
if(!quote_opened){
//如果不是在注釋重
if(!slash_slash_comment_opened && !
slash_star_comment_opened){
//不是在定義變量時
if(!var_opened){
if(this.translateVar
(cur_var_map,codeArr[i])==""){
htmlTxt[htmlTxt.length] =
codeArr[i];
}else{
htmlTxt[htmlTxt.length] =
this.translateVar(cur_var_map,codeArr[i]);
}
}else{
//不是在暫停變量定義時
if(var_pause){
if(this.translateVar
(cur_var_map,codeArr[i])==""){
htmlTxt[htmlTxt.length] =
codeArr[i];
}else{
htmlTxt[htmlTxt.length] =
this.translateVar(cur_var_map,codeArr[i]);
}
}else{
//變量符合命名規(guī)則,并且(變量
前為空格或制表符或逗號如:var a;var a;var a,b;,還有如果是
函數(shù)參數(shù),如:function(a,b,c)
if(this.isVar(codeArr[i])&&
(i>0&&codeArr[i-1]==" "||codeArr[i-1]=="\t"||codeArr[i-1]
==this._varContinue||cur_var_map.isParameter)){
var name =
this.getRandName();
cur_var_map.add(codeArr
[i],name);
htmlTxt[htmlTxt.length] =
this.translateVar(cur_var_map,codeArr[i]);
}else{
htmlTxt[htmlTxt.length] =
codeArr[i];
}
}
}
//注釋中
}else{
if(!this._deleteComment){
htmlTxt[htmlTxt.length] = codeArr
[i];
}
}
}else{
if(execute_opened){
if(this.translateVar
(cur_var_map,codeArr[i])==""){
htmlTxt[htmlTxt.length] = codeArr
[i];
}else{
htmlTxt[htmlTxt.length] =
this.translateVar(cur_var_map,codeArr[i]);
}
}else{
htmlTxt[htmlTxt.length] = this.toHex
(codeArr[i]);
}
}
}
}
return htmlTxt.join("");
}
this.isStartWith = function(str,code,index){
if(typeof(str)!="undefined"&&str.length>0){
var cc = new Array();
for(var i=index;i<index+str.length;i++){
cc[cc.length] = code[i];
}
var c = cc.join("");
if(this._caseSensitive){
if(str.length>=code[index].length&&c.indexOf
(str)==0){
return true;
}
}else{
if(str.length>=code
[index].length&&c.toLowerCase().indexOf(str.toLowerCase())
==0){
return true;
}
}
return false;
} else {
return false;
}
}
this.isFunction = function(val){
return this._function.contains(this._caseSensitive?
val:val.toLowerCase());
}
this.isKeyword = function(val) {
return this._keywords.contains(this._caseSensitive?
val:val.toLowerCase());
}
this.isWindow = function(val) {
return this._window.contains(this._caseSensitive?
val:val.toLowerCase());
}
this.isCommonObject = function(val) {
return this._commonObjects.contains
(this._caseSensitive?val:val.toLowerCase());
}
this.getSkipLength = function(val){
var count = 0;
for(var i=0;i<val.length;i++){
if(this._wordDelimiters.indexOf(val.charAt(i))
>=0){
count++;
}
}
if(count>0){
count=count-1;
}
return count;
}
//字符串轉(zhuǎn)換為16進(jìn)制形式
this.toHex = function(val){
var str = new Array();
for(var i=0;i<val.length;i++){
var c = val.charCodeAt(i);
if(c>=0&&c<256){
str[str.length] = "\\x" + val.charCodeAt
(i).toString(16);
}else{
str[str.length] = "\\u" + val.charCodeAt
(i).toString(16);
}
}
return str.join("");
}
//獲得變量隨機(jī)名
this.getRandName = function(){
var style = parseInt(Math.random()*4);
var len = parseInt(Math.random()*9)+1;
var n = [];
this._varNum++;
var c =
"abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
for(var i=0;i<len;i++){
n[n.length] = c.charAt(parseInt(Math.random()
*54));
}
return n.join("")+this._varNum;
}
//是否符合變量命名字首規(guī)則
this.isVar = function(val){
return /^[a-zA-Z_\$].*$/.test(val);
}
//翻譯變量,如果返回為空則不存在此變量
this.translateVar = function(node,key){
if(node.contains(key)){
return node.items(key);
}
var cn = node.parent;
while(cn!=null){
if(cn.contains(key)){
return cn.items(key);
}
cn = cn.parent;
}
return "";
}
}
function doConfusion(o){
var htmltxt = "";
if (o == null){
alert("domNode is null!");
return;
}
var _codetxt = "";
if(typeof(o)=="object"){
switch(o.tagName){
case "TEXTAREA":
case "INPUT":
_codetxt = o.value;
break;
case "DIV":
case "SPAN":
_codetxt = o.innerText;
break;
default:
_codetxt = o.innerHTML;
break;
}
}else{
_codetxt = o;
}
var _syn = new CLASS_CONFUSION(_codetxt);
htmltxt = _syn.confusion();
return htmltxt;
}
function go()
{
var code = document.getElementById("code").value;
var xx = new CLASS_CONFUSION(code);
var a = new Date();
document.getElementById("display").value = xx.confusion();
alert("共花:" + (new Date().getTime()-a.getTime()) +
"ms");
}
//-->
</SCRIPT>
相關(guān)文章
Javascript面向?qū)ο笤O(shè)計一 工廠模式
工廠模式抽象了創(chuàng)建具體對象的過程,但是在ECMAScript中無法創(chuàng)建類,所以就使用一種函數(shù)來封裝以特定接口創(chuàng)建對象的細(xì)節(jié)2011-12-12面向?qū)ο蟮腏avascript之二(接口實(shí)現(xiàn)介紹)
接口是面向?qū)ο驤avascript工具箱中最有用的特性之一。我們都知道GOF在設(shè)計模式中說到:面向接口編程,而非面向?qū)崿F(xiàn)編程2012-01-01javascript 面向?qū)ο蟮腏avaScript類
這一節(jié)來說下緊接著的一個概念——類。雖然JavaScript中沒有class關(guān)鍵字,但作為開發(fā)人員我們一定要有這個思想。在C#中類可以分為實(shí)例類和靜態(tài)類,JavaScript亦然。2010-05-05javascript 面向?qū)ο缶幊? function是方法(函數(shù))
在進(jìn)行編程時,必免不了要碰到復(fù)雜的功能。初學(xué)者最怕復(fù)雜的功能,因為不能夠很好的進(jìn)行功能邊界劃分,只能一大串if、循環(huán)加case堆疊在一起,結(jié)果出來的程序自己看著暈,別人看著更暈。2009-09-09XRegExp 0.2: Now With Named Capture
XRegExp 0.2: Now With Named Capture...2007-11-11javascript 面向?qū)ο蟮慕?jīng)典實(shí)例代碼
這里的面向?qū)ο笾饕鞘褂胮rototype屬性,大家可以參考下。2009-12-12Javascript 類與靜態(tài)類的實(shí)現(xiàn)
在Javascript里,對面向?qū)ο蟛]有一個直接的實(shí)現(xiàn),對于代碼方面也是非常的靈活。2010-04-04