惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
L
LINUX DO - 热门话题
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
D
Docker
C
Cyber Attacks, Cyber Crime and Cyber Security
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
Google DeepMind News
Google DeepMind News
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
The Hacker News
The Hacker News
Project Zero
Project Zero
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
Jina AI
Jina AI
Cyberwarzone
Cyberwarzone
The Register - Security
The Register - Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Vercel News
Vercel News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Scott Helme
Scott Helme
A
About on SuperTechFans
WordPress大学
WordPress大学
F
Fortinet All Blogs
大猫的无限游戏
大猫的无限游戏
G
GRAHAM CLULEY
Latest news
Latest news
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Schneier on Security

博客园 - ttyp

火苗-批量改名最新V1.0.5 喂来猫-超强工具集最新版 V1.0.9.0 使用MemberShip时,用HttpWebRequest抓数据 ASP.NET图形化的曲线图类 JS写的一个功能齐备的treeview控件 输入自动完成类 定时检查网站是否掉线的批处理 code collection 0.44版 发布 JS代码的格式化和压缩 OUTLOOK菜单类 WEB打印分页类(JS) - ttyp - 博客园 自动配置IE代理脚本 XP下IIS不能添加扩展名映射的BUG js编写的语法高亮引擎 js写的Hashtable类 INF文件格式小结 自动提示效果 超强的WEB表格组件 关于设置WebControls里的treeview控件的图片路径
JS代码混淆初步
ttyp · 2006-03-20 · via 博客园 - ttyp

一直以来,JS前端代码因为必须经过IE明文解析,某些加密的JS如:JScript.Encode也因为树大招风,早就被人破解了。还有些加密的手段,通过复杂的变换,改变源码,但最终都逃不脱最后的审判,像unescape,document.write,eval语句来还原。对于JS代码的保护,最好的手段就是混淆,混淆的目的就是让读懂代码的成本比直接写代码的成本高,混淆不是不可破解的,只是增加破解成本,JAVA,C#的加密都是采用混淆。这样对于非常核心的代码,混淆起不到保护代码的作用,不过JS有这样的代码么?本程序没有用到编译原理,其分词解析思想是基于mechiland(http://www.jzchen.net)的代码高亮程序,参考了蓝色经典的加密混淆专题讨论

<HTML><HEAD><TITLE>Cunfusion</TITLE>
<META content="MSHTML 6.00.2800.1528" name=GENERATOR>
<META content="" name=Author>
<META content="" name=Keywords>
<META content="" name=Description></HEAD>
<BODY>
<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;

    
//字符串转换为哈希表
    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;
    }


    
//获得需要转换的代码
    this._codetxt        = code;

    
if(typeof(syntax)=="undefined"){
        syntax 
= "";
    }


    
this._deleteComment = false;
    
//是否大小写敏感
    this._caseSensitive    = true;
    
//得到关键字哈希表
    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,else,do,var");
    
this._function        = this.str2hashtable("function");
    
this._var            = "var";
    
this._beginBlock    = "{";
    
this._endBlock        = "}";
    
    
this._window        = this.str2hashtable("alert,escape,unescape,document,parseInt,parseFloat");
    
//得到内建对象哈希表
    this._commonObjects = this.str2hashtable("String,Number,Boolean,RegExp,Error,Math,Date,Object,Array,Global");
    
//得到分割字符
    this._wordDelimiters= "  ,.?!;:\\/<>(){}[]\"'\r\n\t=+-|*%@#$^&";
    //引用字符
    this._quotation        = this.str2hashtable(
"\",'");
    
//行注释字符
    this._lineComment    = "//";
    
//转义字符
    this._escape        = "\\";
    
//多行引用开始
    this._commentOn        = "/*";
    
//多行引用结束
    this._commentOff    = "*/";
    
this._execute        = "eval";
    
//引用调用字符
    this._call            = ".";
    
this._varPause        = "=";
    
this._varContinue    = ",";
    
//变量个数
    this._varNum = 0;

    
this.confusion    = function() {
        
var codeArr = new Array();
        
var word_index = 0;
        
var htmlTxt = new Array();


        
//得到分割字符数组(分词)
        for (var i = 0; i < this._codetxt.length; i++{
            
            
if (this._wordDelimiters.indexOf(this._codetxt.charAt(i)) == -1{        //找不到关键字
                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;    //引用标记
        var slash_star_comment_opened    = false;    //多行注释标记
        var slash_slash_comment_opened    = false;    //单行注释标记
        var line_num                    = 1;        //行号
        var quote_char                    = "";        //引用标记类型
        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++){

            
//单独处理指针引用
            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;
            }

            
            
//处理空行(由于转义带来)
            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里的参数标记
            }
 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];
            
//处理引用调用
            }
 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;
                }

            
//处理关键字
            }
 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内置对象
            }
 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]) + "\"]";
            
//处理双引号(引号前不能为转义字符)    
            }
 else if (!slash_star_comment_opened&&!slash_slash_comment_opened&&this._quotation.contains(codeArr[i])){                                                    
                
if (quote_opened){
                    
//是相应的引号
                    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];
                }
                    
            
//处理转义字符
            }
 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);                    
            
//处理多行注释结束    
            }
 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{
                                
//变量符合命名规则,并且(变量前为空格或制表符或逗号如:var a;var    a;var a,b;,还有如果是函数参数,如: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;
    }


    
//字符串转换为16进制形式
    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("");
    }


    
//获得变量随机名
    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;

    }


    
//是否符合变量命名字首规则
    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>
<TEXTAREA id=code rows=12 cols=100>
/*
这个是一个类
*/
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;}}
}

xx.prototype.dd
= function(){
alert("dd");
}

var a 
= new xx(100,"hello"),b=new xx(0,"ttyp");
eval("a.aa
=20");
a.bb();
b.dd();
alert(a.aa);

</TEXTAREA
> <BR><INPUT onclick=go() type=button value=go><br>
<textarea id=display rows=12 cols=100>
</textarea>
</BODY></HTML>

最后,本人原则上不赞成代码混淆加密,写本程序是出于研究目的,本程序本人原创,后续的代码压缩等功能陆续加上,程序中有任何问题请指正,任何转载请写明出处。