Auto-Fill-Verification-Code-Box-of-ZJU

自动填写浙大图书馆预约系统验证码

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        Auto-Fill-Verification-Code-Box-of-ZJU
// @author      HsFish1213
// @namespace   https://github.com/HsFish1213/Auto-Fill-Verification-Code-Box-of-ZJU
// @description 自动填写浙大图书馆预约系统验证码
// @include     http://10.203.97.155/home/book*
// @require     https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js
// @version     3.0
// @grant       none
// @run-at      document-start
// @license MIT
// ==/UserScript==

var $ = window.jQuery;

(function() {
	alert("Please click login in 3 seconds.Then I'll auto-fill the verifying box every 2 seconds.");
	//$('a.badge login-btn login_click').trigger("click");
	//$('a.login-btn login_click').trigger("click");
    //$(".login-btn").trigger("click");
	setTimeout (function ()
	{Main();}, 3000);

	function Main(){
		var img = document.getElementById("checkpic");
		console.log("Time is up");
        //$('input[name=verify]').val("Test");//for test
		//document.getElementsByName("verify").value="lalala";
        console.log(img.src);//for test
        //$("#imgCode").hide();
		var canvas = document.createElement('canvas');//创建画布
		document.body.appendChild(canvas);
		canvas.width = 130;
		canvas.height= 50;

		var ctx;
		var imgArr = [];

		//console.log("Draw happens!");//开始绘入img (for test)
		if (!canvas.getContext) return;
		ctx = canvas.getContext("2d");
		ctx.drawImage(img, 0, 0);

		//console.log("Getting code!");//for test
		var imgData_obj = ctx.getImageData(0,0,canvas.width,canvas.height);// 获取画布上的图像像素矩阵
		var imgData = imgData_obj.data;// 获取到的数据为一维数组,包含图像的RGBA四个通道数据

		var Gmain=getTheMainColor();//获取主要的颜色
		function getTheMainColor(){
			var kind=[];//各种颜色的集合
			var kindN=1;//颜色种类数
			var kindS=[];//不同种颜色的面积
			for (var i=0;i<=130-1;i++){
				for (var j=0;j<=50-1;j++){
					kindS.push(0);
					var colorNow=imgData[4*(130*j+i)];
					if(colorNow!=243 && findTheKind(colorNow)==0){
						kind[kindN]=colorNow;
						kindS[kindN]++;
						kindN++;
					}
					else if(colorNow!=243){
						kindS[findTheKind(colorNow)]++;
					}
				}
			}

			function findTheKind(a){//找到所在颜色类型
				for (var i=1;i<=kindN;i++){
					if (a==kind[i]){
						return i;
					}
				}
				return 0;
			}
			var mainKindId = 1;
			for (var iii=1;iii<=kindN;iii++){//计算得到主要的颜色
					if (kindS[mainKindId]<kindS[iii])
                    {mainKindId=iii;}
			}
			return kind[mainKindId];
		}

		var ee=88;
		var boolColor = new Array(130);//存储背景、数字以及轮廓的矩阵
		var boolEachColor = new Array(5);//分别储存每个数字的矩阵
		var boolEachGet = new Array(5);//分别储存每个数字get
		for (var index=1;index<=4;index++){
			boolEachColor[index]=new Array(130);
			boolEachGet[index]=new Array(130);
		}
        var boolTest = new Array(130);//for test
		var boolGet = new Array(130);//是否已经检测
		for (var i=0;i<=130-1;i++){
			boolColor[i]=new Array(50);
			for (var z=1;z<=4;z++){boolEachColor[z][i]=new Array(50);boolEachGet[z][i]=new Array(50);}
            boolTest[i]=new Array(50);
			boolGet[i]=new Array(50);
			for (var j=0;j<=50-1;j++){
				if(imgData[4*(130*j+i)]==243)
					{boolColor[i][j]="";}
				else if(imgData[4*(130*j+i)]==Gmain)
					{boolColor[i][j]=11;}
				else boolColor[i][j]=ee;
				for (var index2=1;index2<=4;index2++){boolEachColor[index2][i][j]="";boolEachGet[index2][i][j]="";}
                boolTest[i][j]="";
				boolGet[i][j]="";
			}
		}


		var mainS=[0,0,0,0,0];//4个数字的主颜色面积 1-4
		var edgeS=[0,0,0,0,0];//4个数字的轮廓面积 1-4
		var holeS=[0,0,0,0,0];//4个数字的孔洞面积 1-4
		//var big=[0];//4个数字的大块中心数量  1-4

		getTheCode1();

		function getTheCode1(){//开始逐一拓展
			var n=1;
			for (var i=0;i<=130-1;i++){
				for (var j=0;j<=50-1;j++){
					if (boolGet[i][j]==""&&boolColor[i][j]==11){
						expand(i,j,n);
						n++;
					}
				}
			}
		}


		function expand(i,j,n){//使用递归 由一点拓展到整个数字
            boolGet[i][j]=11;
            boolTest[i][j]=11;//for test
            if(boolColor[i][j]==11){mainS[n]+=1;boolEachColor[n][i][j]=11;}
			if(boolColor[i][j]==ee){edgeS[n]+=1;boolEachColor[n][i][j]=ee;}//important
            //console.log("Expanding "+i+" "+j);//for test
			var iplus=[1,-1,0,0];
			var jplus=[0,0,1,-1];
			for(var m=0;m<=3;m+=1){
				var ii=i+iplus[m];
				var jj=j+jplus[m];
				if(0<=ii&&ii<=130-1&&0<=jj&&jj<=50-1&&boolGet[ii][jj]==""){
					if(boolColor[ii][jj]==11||boolColor[ii][jj]==ee){
						expand(ii,jj,n);
					}
				}
			}
		}

		if(mainS[4]==0){refresh();return;}

		function getAverage(n){//获得一个数字矩阵的main和edge的均坐标作为特征
			var mainXSum=0,mainYSum=0;
			var edgeXSum=0,edgeYSum=0;
			var aver=[];
			for (var i=0;i<=130-1;i++){
				for (var j=0;j<=50-1;j++){
					if (boolEachColor[n][i][j]==11){
						mainXSum+=i;
						mainYSum+=j;
					}
					if (boolEachColor[n][i][j]==ee){
						edgeXSum+=i;
						edgeYSum+=j;
					}
				}
			}
			aver[1]=mainXSum/mainS[n];aver[2]=mainYSum/mainS[n];
			aver[3]=edgeXSum/edgeS[n];aver[4]=edgeYSum/edgeS[n];
			return aver;
		}

		var aver=new Array(5);
		var vector=new Array(5);//每个数字的特征矢量 1-4
		var vectLength=new Array(5);//每个数字的特征矢量长度 1-4
		var hole=[0];//每个数字的洞口数量 1-4
		for(var index5=1;index5<=4;index5++){
			aver[index5]= getAverage(index5);
			vector[index5]=[aver[index5][1]-aver[index5][3],aver[index5][2]-aver[index5][4]];
			vectLength[index5]=Math.pow(vector[index5][0],2)+Math.pow(vector[index5][1],2);
			hole.push(numberOfHole(index5));
			//big.push(getBig(index5));
		}


		function numberOfHole(n){//开始逐一拓展检查孔洞,返回孔洞数目
			var ans=0;
			var iTo=130,jTo=50;
			expandHole(0,0,n,1);
			for (var i=0;i<=iTo-1;i++){
				for (var j=0;j<=jTo-1;j++){
					if (boolEachGet[n][i][j]==""&&boolEachColor[n][i][j]==""){
						expandHole(i,j,n,2);
						ans++;
					}
				}
			}

			function expandHole(i,j,n,mode){//使用递归 由一点拓展到整个hole. Mode:1背景 2孔洞
				boolEachGet[n][i][j]=11;
				if(mode==2){holeS[n]+=1;}
				//console.log("Expanding "+i+" "+j);//for test
				var iplus=[1,-1,0,0];
				var jplus=[0,0,1,-1];
				for(var m=0;m<=3;m+=1){
					var ii=i+iplus[m];
					var jj=j+jplus[m];
					if(0<=ii&&ii<=130-1&&0<=jj&&jj<=50-1&&boolEachGet[n][ii][jj]==""){
						if(boolEachColor[n][ii][jj]==""||boolEachColor[n][ii][jj]==ee){
							expandHole(ii,jj,n,mode);
						}
					}
				}
			}
			return ans;
		}
		/*
		function getBig(n){
			var ansBig=0;
			var r=2;//半径--------
			for (var x=0+r;x<=130-1-r;x++){
				for (var y=0+r;y<=50-1-r;y++){
					if(ifBig(x,y,n)==1){ansBig++;}
				}
			}
			function ifBig(x,y,n){
				var ansIfBig=1;
				for (var ii=x+(-1)*r;ii<=x+r;ii++){
					for (var jj=y+(-1)*r;jj<=y+r;jj++){
						if(boolEachColor[n][ii][jj]==""){ansIfBig=0;}
					}
				}
				return ansIfBig;
			}
			return ansBig;
		}*/
		/*
		function getHoleS(n){//获取第n个数字的孔洞面积
			var holeS=0,backS=0;
			backS=getBackS(n);
			function getBackS(n){//填充背景矩阵并获得背景面积
				//var boolBackGet=Raw.slice();
				var boolBackGet=Array.from(Raw);
				var ansBackS=0;
				expandBack(0,0,n);
				function expandBack(i,j,n){//使用递归由一点拓展到整个背景
					boolBackGet[i][j]=11;
					ansBackS++;
					var iplus=[1,-1,0,0];
					var jplus=[0,0,1,-1];
					for(var m=0;m<=3;m+=1){
						var ii=i+iplus[m];
						var jj=j+jplus[m];
						if(0<=ii&&ii<=130-1&&0<=jj&&jj<=50-1&&boolBackGet[ii][jj]==""){
							if(boolEachColor[n][ii][jj]==""||boolEachColor[n][ii][jj]==ee){
								expandBack(ii,jj,n);
							}
						}
					}
				}
				return ansBackS;
			}
			console.log("SHole:"+holeS);//for test
			holeS=130*50-backS-mainS[n];
			return holeS;
			for (var i=0;i<=130-1;i++){
				for (var j=0;j<=50-1;j++){
					if (boolEachGet[n][i][j]==""&&boolEachColor[n][i][j]==""){
					}
				}
			}
		}*/

		var finalAns=[0,0,0,0,0];
		function getAns(n){
			if(mainS[n]<=83&&hole[n]==0){return 1;}
			if(85<=mainS[n]&&mainS[n]<=100&&hole[n]==0){return 7;}
			if(110<=mainS[n]&&mainS[n]<=119&&hole[n]==0){return 3;}
			if(121<=mainS[n]&&mainS[n]<=130){return which245();}
			if(131<=mainS[n]&&mainS[n]<=150){return which0689();}

			function which245(){
				if(hole[n]==1){return 4;}
				if(hole[n]==0){return which25v3ByVect();}//-choose-
				function which25v1(){//main:模糊方案
					if(115<=mainS[n]&&mainS[n]<=125){return 2;}
					if(126<=mainS[n]&&mainS[n]<=130){return 5;}
				}
				function which25v2(){//main:刷新以求准确方案
					if(115<=mainS[n]&&mainS[n]<=123){return 2;}
					if(127<=mainS[n]&&mainS[n]<=130){return 5;}
					return -1;
				}
				function which25v3ByVect(){//vect:观察半天输出得到的参数界定 still not good enough
					if((vector[n][0]>0.09&&vector[n][1]<0.06)||(vector[n][0]<-0.06&&vector[n][1]<-0.1)||vector[n][1]<-0.6||vector[n][0]>0.68){return 2;}
					else return 5;
				}
				return -1;
			}

			function which0689(){
				if(hole[n]==2){return 8;}
				if(hole[n]==1){return which069();}
				function which069(){//通过特征矢量方向判断
					//getHoleS(n);
					if(holeS[n]>=40){return 0;}
					if(5<=holeS[n]&&holeS[n]<=25){return which69ByVectSign();}
					function which69ByVectSign(){
						if(vector[n][0]>0&&vector[n][1]<0){return 9;}
						if(vector[n][0]<0&&vector[n][1]>0){return 6;}
						return -1;
					}
					return -1;
				}
				return -1;
			}

			return -1;//说明错误:自动刷新
		}
		for(var index6=1;index6<=4;index6++){
			finalAns[index6]=getAns(index6);
			if(finalAns[index6]==-1){refresh();return;}//如果出错则刷新
		}


		//特征数据流
		console.log("Main: "+mainS[1]+" "+mainS[2]+" "+mainS[3]+" "+mainS[4]);//输出4个数字的main面积
		console.log("Edge: "+edgeS[1]+" "+edgeS[2]+" "+edgeS[3]+" "+edgeS[4]);//输出4个数字的edge面积
		console.log("Hole: "+hole[1]+" "+hole[2]+" "+hole[3]+" "+hole[4]);//输出4个数字的hole
		console.log("HoleS: "+holeS[1]+" "+holeS[2]+" "+holeS[3]+" "+holeS[4]);//输出4个数字的hole面积
		//console.log("Big: "+big[1]+" "+big[2]+" "+big[3]+" "+big[4]);//输出4个数字的big
		for(var index4=1;index4<=4;index4++){
			console.log("Vect"+index4+":"+vectLength[index4]+"|"+vector[index4]);
		}
		console.log("Code: "+finalAns[1]+" "+finalAns[2]+" "+finalAns[3]+" "+finalAns[4]);//输出4个数字
		//console.log(boolEachColor);//for test
		//console.log(boolColor);//for test
        //console.log(boolGet);//for test
        //console.log(boolTest);//for test

		$('input[name=verify]').val(""+finalAns[1]+finalAns[2]+finalAns[3]+finalAns[4]);

		console.log("----------------------------");

		function refresh(){//刷新验证码并且递归
			$('#checkpic').trigger("click");
			setTimeout (function ()
			{
				Main();
			}, 500);
		}


		setTimeout (function ()//每3秒自动刷新并且循环一次
		{
			refresh();
		}, 2000);


		/*
		for(var i=0; i<=4*6500-1; i += 4){
			//imgData.length
			imgArr.push(imgData[i], imgData[i+1], imgData[i+2]);
			boolColor.push(imgData[i]);
            if(imgData[i]!=243)
			{
                console.log(i+" "+imgData[i]);
            }
		}*/
		//感悟:要想提高准确性就得不断获取新的特征以区分(当然刷新也是个方法)
	}
})();