Packer,你对我的JS代码做了什么?

Packer,你对我的JS代码做了什么?

代码

源码

最近写了个代码,如下

/*
 * Tool-v1.0.0.js 
 * 
 * Copyright (c) 2023 Robert Rain 
 * 
 * $Date:undefined
 */
; (function(global) {
	function ToolJS() {
		var lib = {};
		lib.time = new Date().toJSON();
		lib.query = function(selector) {
			if (selector) {
				return document.querySelectorAll(selector);
			} else {
				throw new Error();
			}
		}
		lib.tobase = function(number, baseNum) {
			if (typeof number === "number" || typeof baseNum === "number") {
				return number.toString(baseNum);
			} else {
				throw new Error();
			}
		}
		lib.getproto = function(obj) {
			return obj.__proto__;
		}
		lib.toArray = function(arr) {
			return [].concat(arr);
		}

		lib.addZero = function(a) {
			return (a < 10 ? '0': '') + a
		}

		lib.humpToHyphen = function(a) {
			if (typeof a === 'string') {
				return a.replace(/([A-Z])/g, '-$1').toLowerCase()
			}
			return a
		}

		lib.formatDate = function(date, fmt) {
			const that = new Date(date);
			var o = {
				'M+': that.getMonth() + 1,
				'd+': that.getDate(),
				'h+': that.getHours(),
				'm+': that.getMinutes(),
				's+': that.getSeconds(),
				'q+': Math.floor((that.getMonth() + 3) / 3),
				S: that.getMilliseconds()
			};
			if (/(y+)/.test(fmt)) {
				fmt = fmt.replace(RegExp.$1, (that.getFullYear() + '').substr(4 - RegExp.$1.length))
			}
			for (var k in o) {
				if (new RegExp('(' + k + ')').test(fmt)) {
					fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
				}
			}
			return fmt
		}

		lib.delay = function(callFunc, condition, interval = 100) {
			const _delay = (callFunc, condition, interval) = >{
				let TIMER = null;
				TIMER = setTimeout(function() {
					if (condition()) {
						clearTimeout(TIMER);
						callFunc()
					} else {
						_delay(callFunc, condition, interval)
					}
				},
				interval)
			};
			if (condition()) {
				callFunc()
			} else {
				_delay(callFunc, condition, interval)
			}
		}
		lib.throttle = function(fn, delay) {
			let timer = null;
			return function() {
				clearTimeout(timer);
				timer = setTimeout(function() {
					fn.bind(this)(arguments)
				},
				delay)
			}
		};

		lib.safeExecuteFunc = function(a, b) {
			if (typeof a === 'function') {
				try {
					return a(b)
				} catch(err) {
					console.error(err)
				}
			} else {
				console.warn('Func cannot execute', a)
			}
			return undefined
		}

		lib.toggleFullScreen = function(a) {
			if (a === undefined) {
				a = !(document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen)
			}
			var b = document.documentElement;
			if (a) { (b.requestFullscreen && b.requestFullscreen()) || (b.mozRequestFullScreen && b.mozRequestFullScreen()) || (b.webkitRequestFullscreen && b.webkitRequestFullscreen()) || (b.msRequestFullscreen && b.msRequestFullscreen())
			} else {
				const exitFullscreen = document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen;
				exitFullscreen && exitFullscreen()
			}
			return a
		}

		lib.dataURLtoBlob = function(a) {
			var b = a.split(',');
			var c = b[0].match(/:(.*?);/)[1];
			var d = atob(b[1]);
			var n = d.length;
			var e = new Uint8Array(n);
			while (n--) {
				e[n] = d.charCodeAt(n)
			}
			return new Blob([e], {
				type: c
			})
		}

		lib.recursionFunc = function(a, b, c) {
			let result = null;
			if (!a) {
				return
			}
			for (let i in a) {
				if (result !== null) {
					break
				}
				let item = a[i]
				if (item[b] == c) {
					result = item;
					break
				} else if (item.children && item.children.length > 0) {
					result = this.recursionFunc(item.children, c)
				}
			}
			return result
		}

		lib.handleRecur = function(a, b) {
			return a.reduce((iter, val) = >{
				val[b].length ? val[b] = this.handleRecur(val[b]) : delete val[b];
				iter.push(val);
				return iter
			},
			[])
		}
		return lib;
	}
	global.tool = new ToolJS();
})(typeof window !== "underfind" ? window: this);

觉得挺长,就用Packer压缩了一下,结果…

Packer压缩后的代码

成了这样

;(function(g){function ToolJS(){var f={};f.time=new Date().toJSON();f.query=function(a){if(a){return document.querySelectorAll(a)}else{throw new Error();}}f.tobase=function(a,b){if(typeof a==="number"||typeof b==="number"){return a.toString(b)}else{throw new Error();}}f.getproto=function(a){return a.__proto__}f.toArray=function(a){return[].concat(a)}f.addZero=function(a){return(a<10?'0':'')+a}f.humpToHyphen=function(a){if(typeof a==='string'){return a.replace(/([A-Z])/g,'-$1').toLowerCase()}return a}f.formatDate=function(a,b){const that=new Date(a);var o={'M+':that.getMonth()+1,'d+':that.getDate(),'h+':that.getHours(),'m+':that.getMinutes(),'s+':that.getSeconds(),'q+':Math.floor((that.getMonth()+3)/3),S:that.getMilliseconds()};if(/(y+)/.test(b)){b=b.replace(RegExp.$1,(that.getFullYear()+'').substr(4-RegExp.$1.length))}for(var k in o){if(new RegExp('('+k+')').test(b)){b=b.replace(RegExp.$1,(RegExp.$1.length===1)?(o[k]):(('00'+o[k]).substr((''+o[k]).length)))}}return b}f.delay=function(a,b,c){const _delay=(a,b,interval)=>{let TIMER=null;TIMER=setTimeout(function(){if(b()){clearTimeout(TIMER);a()}else{_delay(a,b,interval)}},interval)};if(b()){a()}else{_delay(a,b,interval)}}f.throttle=function(a,b){let timer=null;return function(){clearTimeout(timer);timer=setTimeout(function(){a.bind(this)(arguments)},b)}};f.safeExecuteFunc=function(a,b){if(typeof a==='function'){try{return a(b)}catch(err){console.error(err)}}else{console.warn('Func cannot execute',a)}return undefined}f.toggleFullScreen=function(a){if(a===undefined){a=!(document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen)}var b=document.documentElement;if(a){(b.requestFullscreen&&b.requestFullscreen())||(b.mozRequestFullScreen&&b.mozRequestFullScreen())||(b.webkitRequestFullscreen&&b.webkitRequestFullscreen())||(b.msRequestFullscreen&&b.msRequestFullscreen())}else{const exitFullscreen=document.exitFullscreen||document.mozCancelFullScreen||document.webkitExitFullscreen;exitFullscreen&&exitFullscreen()}return a}f.dataURLtoBlob=function(a){var b=a.split(',');var c=b[0].match(/:(.*?);/)[1];var d=atob(b[1]);var n=d.length;var e=new Uint8Array(n);while(n--){e[n]=d.charCodeAt(n)}return new Blob([e],{type:c})}f.recursionFunc=function(a,b,c){let result=null;if(!a){return}for(let i in a){if(result!==null){break}let item=a[i]if(item[b]==c){result=item;break}else if(item.children&&item.children.length>0){result=this.recursionFunc(item.children,c)}}return result}f.handleRecur=function(a,b){return a.reduce((iter,val)=>{val[b].length?val[b]=this.handleRecur(val[b]):delete val[b];iter.push(val);return iter},[])}return f}g.tool=new ToolJS()})(typeof window!=="underfind"?window:this);

然后我又压了一下,我艹,更乱了

eval(function(p,a,c,k,e,r){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--)r[e(c)]=k[c]||e(c);k=[function(e){return r[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}(';(2(g){2 L(){7 f={};f.1c=9 N().1d();f.1e=2(a){6(a){5 j.1f(a)}l{O 9 P();}}f.1g=2(a,b){6(u a==="Q"||u b==="Q"){5 a.1h(b)}l{O 9 P();}}f.1i=2(a){5 a.1j}f.1k=2(a){5[].1l(a)}f.1m=2(a){5(a<10?\'0\':\'\')+a}f.1n=2(a){6(u a===\'1o\'){5 a.E(/([A-Z])/g,\'-$1\').1p()}5 a}f.1q=2(a,b){F 8=9 N(a);7 o={\'M+\':8.R()+1,\'d+\':8.1r(),\'h+\':8.1s(),\'m+\':8.1t(),\'s+\':8.1u(),\'q+\':1v.1w((8.R()+3)/3),S:8.1x()};6(/(y+)/.T(b)){b=b.E(v.$1,(8.1y()+\'\').U(4-v.$1.p))}V(7 k W o){6(9 v(\'(\'+k+\')\').T(b)){b=b.E(v.$1,(v.$1.p===1)?(o[k]):((\'1z\'+o[k]).U((\'\'+o[k]).p)))}}5 b}f.1A=2(a,b,c){F G=(a,b,z)=>{w H=B;H=X(2(){6(b()){Y(H);a()}l{G(a,b,z)}},z)};6(b()){a()}l{G(a,b,z)}}f.1B=2(a,b){w I=B;5 2(){Y(I);I=X(2(){a.1C(C)(1D)},b)}};f.1E=2(a,b){6(u a===\'2\'){1F{5 a(b)}1G(11){12.1H(11)}}l{12.1I(\'1J 1K 1L\',a)}5 13}f.1M=2(a){6(a===13){a=!(j.1N||j.1O||j.1P)}7 b=j.1Q;6(a){(b.14&&b.14())||(b.15&&b.15())||(b.16&&b.16())||(b.17&&b.17())}l{F D=j.D||j.1R||j.1S;D&&D()}5 a}f.1T=2(a){7 b=a.1U(\',\');7 c=b[0].1V(/:(.*?);/)[1];7 d=1W(b[1]);7 n=d.p;7 e=9 1X(n);1Y(n--){e[n]=d.1Z(n)}5 9 20([e],{21:c})}f.18=2(a,b,c){w x=B;6(!a){5}V(w i W a){6(x!==B){19}w r=a[i]6(r[b]==c){x=r;19}l 6(r.J&&r.J.p>0){x=C.18(r.J,c)}}5 x}f.1a=2(a,b){5 a.22((K,t)=>{t[b].p?t[b]=C.1a(t[b]):23 t[b];K.24(t);5 K},[])}5 f}g.25=9 L()})(u 1b!=="26"?1b:C);',62,131,'||function|||return|if|var|that|new||||||||||document||else||||length||item||val|typeof|RegExp|let|result||interval||null|this|exitFullscreen|replace|const|_delay|TIMER|timer|children|iter|ToolJS||Date|throw|Error|number|getMonth||test|substr|for|in|setTimeout|clearTimeout|||err|console|undefined|requestFullscreen|mozRequestFullScreen|webkitRequestFullscreen|msRequestFullscreen|recursionFunc|break|handleRecur|window|time|toJSON|query|querySelectorAll|tobase|toString|getproto|__proto__|toArray|concat|addZero|humpToHyphen|string|toLowerCase|formatDate|getDate|getHours|getMinutes|getSeconds|Math|floor|getMilliseconds|getFullYear|00|delay|throttle|bind|arguments|safeExecuteFunc|try|catch|error|warn|Func|cannot|execute|toggleFullScreen|fullScreen|mozFullScreen|webkitIsFullScreen|documentElement|mozCancelFullScreen|webkitExitFullscreen|dataURLtoBlob|split|match|atob|Uint8Array|while|charCodeAt|Blob|type|reduce|delete|push|tool|underfind'.split('|'),0,{}))

Packer介绍

packer是由国外JS大牛Dean Edwards开发的一款JS压缩混淆工具,_但是_JS混淆后体积有亿点大,所以大文件JS压缩会用到UglifyJS

Packer解析

其实packer看着很唬人,破解时eval(function(p,a,c,k,e,r){...也是一个“拦路虎”,但是在我面前什么老虎都是纸糊的!!!
其实把packer代码格式化,就能明白,其实Shrink Variables就是把变量压缩,去注释、换行等,但是Base62 Encode就比较变态了,但我看了20分钟后终于搞明白了⥥

// p 将原始内容中所有单词替换为字典下标后的压缩内容
// a 词典大小,暂时用不到 
// c 词典大小,在解压时用来关联压缩内容和词典
// k 词典
// e 在解压时,当replace第二个参数支持function时,为\\w+,否则为与下标对应的字符串
// r 当加速解压时用来保存词典
eval(function(p, a, c, k, e, r) {
	e = function(c) {
		return (c < a ? '': e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
	};
	// 检测当前的浏览器是否支持replace(regex, function),如果支持的话就能够加快解压速度
    // 如果不支持的话可以把这一块直接忽略掉
	if (!''.replace(/^/, String)) {
		// 把被压缩的单词拷贝一份,因为k还有别的用处
		while (c--) r[e(c)] = k[c] || e(c);// k[0]后面用来对每个匹配到的下标寻找替换字符串
		k = [function(e) {
			return r[e]
		}];// 用来分割原始内容
		e = function() {
			return '\\w+'
		};// 加速解压的时候,相当于把while变成了if
		c = 1
	};
    // 使用词典将压缩后的下标代码扩展,如果没有上面的加速的话,c等于词典单词数,要一个一个替换了    
    // 如果支持replace(string, function)的话,会将匹配到的每一个数字都传递给k[c]来得到其应该被替换为的字符串
	while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
	// 完成解压
	return p
} (';(2(g){2 L(){7 f={};f.1c=9 N().1d();f.1e=2(a){6(a){5 j.1f(a)}l{O 9 P();}}f.1g=2(a,b){6(u a==="Q"||u b==="Q"){5 a.1h(b)}l{O 9 P();}}f.1i=2(a){5 a.1j}f.1k=2(a){5[].1l(a)}f.1m=2(a){5(a<10?\'0\':\'\')+a}f.1n=2(a){6(u a===\'1o\'){5 a.E(/([A-Z])/g,\'-$1\').1p()}5 a}f.1q=2(a,b){F 8=9 N(a);7 o={\'M+\':8.R()+1,\'d+\':8.1r(),\'h+\':8.1s(),\'m+\':8.1t(),\'s+\':8.1u(),\'q+\':1v.1w((8.R()+3)/3),S:8.1x()};6(/(y+)/.T(b)){b=b.E(v.$1,(8.1y()+\'\').U(4-v.$1.p))}V(7 k W o){6(9 v(\'(\'+k+\')\').T(b)){b=b.E(v.$1,(v.$1.p===1)?(o[k]):((\'1z\'+o[k]).U((\'\'+o[k]).p)))}}5 b}f.1A=2(a,b,c){F G=(a,b,z)=>{w H=B;H=X(2(){6(b()){Y(H);a()}l{G(a,b,z)}},z)};6(b()){a()}l{G(a,b,z)}}f.1B=2(a,b){w I=B;5 2(){Y(I);I=X(2(){a.1C(C)(1D)},b)}};f.1E=2(a,b){6(u a===\'2\'){1F{5 a(b)}1G(11){12.1H(11)}}l{12.1I(\'1J 1K 1L\',a)}5 13}f.1M=2(a){6(a===13){a=!(j.1N||j.1O||j.1P)}7 b=j.1Q;6(a){(b.14&&b.14())||(b.15&&b.15())||(b.16&&b.16())||(b.17&&b.17())}l{F D=j.D||j.1R||j.1S;D&&D()}5 a}f.1T=2(a){7 b=a.1U(\',\');7 c=b[0].1V(/:(.*?);/)[1];7 d=1W(b[1]);7 n=d.p;7 e=9 1X(n);1Y(n--){e[n]=d.1Z(n)}5 9 20([e],{21:c})}f.18=2(a,b,c){w x=B;6(!a){5}V(w i W a){6(x!==B){19}w r=a[i]6(r[b]==c){x=r;19}l 6(r.J&&r.J.p>0){x=C.18(r.J,c)}}5 x}f.1a=2(a,b){5 a.22((K,t)=>{t[b].p?t[b]=C.1a(t[b]):23 t[b];K.24(t);5 K},[])}5 f}g.25=9 L()})(u 1b!=="26"?1b:C);', 62, 131, '||function|||return|if|var|that|new||||||||||document||else||||length||item||val|typeof|RegExp|let|result||interval||null|this|exitFullscreen|replace|const|_delay|TIMER|timer|children|iter|ToolJS||Date|throw|Error|number|getMonth||test|substr|for|in|setTimeout|clearTimeout|||err|console|undefined|requestFullscreen|mozRequestFullScreen|webkitRequestFullscreen|msRequestFullscreen|recursionFunc|break|handleRecur|window|time|toJSON|query|querySelectorAll|tobase|toString|getproto|__proto__|toArray|concat|addZero|humpToHyphen|string|toLowerCase|formatDate|getDate|getHours|getMinutes|getSeconds|Math|floor|getMilliseconds|getFullYear|00|delay|throttle|bind|arguments|safeExecuteFunc|try|catch|error|warn|Func|cannot|execute|toggleFullScreen|fullScreen|mozFullScreen|webkitIsFullScreen|documentElement|mozCancelFullScreen|webkitExitFullscreen|dataURLtoBlob|split|match|atob|Uint8Array|while|charCodeAt|Blob|type|reduce|delete|push|tool|underfind'.split('|'), 0, {}))

还有一个更好的妙招!!!!
把最前面的eval换成String,输入控制台,就会自动输出源代码!

后记

WDNMD,这些东西看着实在头疼,盯着看了20分钟才搞出点名堂,实在太麻烦了,还不如UglifyJS呢
这篇文章就到这里了,下篇文章见,拜拜~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值