微信公众号:创享日记
发送:手势密码
获取完整源码(导入微信开发者工具即可用)
以下可以忽略不看!
手势密码就是在手机触屏上设置一笔连成的九宫格图案,登录时画一下设定的图形。
运行程序,发现各个数字的个数,其中
4位的有1624个,5位的有7152个,6位的有26016个,7位的有72912个,8位的有140704个,9位的有140704个,总共有389112种!
值得一提的是,6位以下的个数甚至每到10000种,所以设置密码最好设置6位以上的,当然不怕忘记的话,可以设置9位的变态密码。
目前app内常用的安全验证,有密码、手势、指纹、面部识别。你会发现从便利性&安全性从高到低的划分是,面部识别、指纹识别、手势、密码。随着时代和技术的进步,安全验证更加趋向于个人生物化。n年前,如果密码被a知道了,a完全可以通过密码/手势来获得和你同样的权利进行相关操作。现在,则可通过生物认证。指纹和面部识别来确定是否是本人进行操作,大大提升了产品的安全性。
使用手势密码登录时,如果输入错误,会对用户进行错误提示,提示后用户可以继续输入,当同一个账号输错达5次时,系统会自动退出登录,用户需要输入密码验证身份成功后才能进入app。
在手势登录页面,也可以使用忘记手势密码登录,如果点击忘记手势密码,退出登录,输入密码验证身份成功后,页面跳转至手势密码设置页面,设置新的手势密码。设置完成后,会自动登录app。
function(){var wxlocker = function(obj){this.chooseType = 3; // 3*3的圆点格子};wxlocker.prototype.drawCle = function(x, y) { // 初始化解锁密码面板this.ctx.setStrokeStyle('#10AEFF');this.ctx.setLineWidth(1);this.ctx.beginPath();this.ctx.arc(x, y, this.r, 0, Math.PI * 2, true);this.ctx.closePath();this.ctx.stroke();}wxlocker.prototype.drawLine = function(po, lastPoint) {// 解锁轨迹this.ctx.beginPath();this.ctx.setLineWidth(1);this.ctx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);for (var i = 1 ; i < this.lastPoint.length ; i++) {this.ctx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);}this.ctx.lineTo(po.x, po.y);this.ctx.stroke();this.ctx.closePath();}wxlocker.prototype.createCircle = function() {// 创建解锁点的坐标,根据canvas的大小来平均分配半径var cavW = this.setCanvasSize().w;var cavH = this.setCanvasSize().h;var n = this.chooseType;var count = 0;this.r = cavW / (2 + 4 * n);// 公式计算this.lastPoint = [];this.arr = [];this.restPoint = [];var r = this.r;for (var i = 0 ; i < n ; i++) {for (var j = 0 ; j < n ; j++) {count++;var obj = {x: j * 4 * r + 3 * r,y: i * 4 * r + 3 * r,index: count};this.arr.push(obj);this.restPoint.push(obj);}}// this.ctx.clearRect(0, 0, cavW, cavH);for (var i = 0 ; i < this.arr.length ; i++) {this.drawCle(this.arr[i].x, this.arr[i].y);}wx.drawCanvas({canvasId: "locker",actions: this.ctx.getActions(),reserve:false});//return arr;}wxlocker.prototype.getPosition = function(e) {// 获取touch点相对于canvas的坐标// var rect = e.target;var po = {x: e.touches[0].x,y: e.touches[0].y};return po;}wxlocker.prototype.update = function(po) {// 核心变换方法在touchmove时候调用var cavW = this.setCanvasSize().w;var cavH = this.setCanvasSize().h;this.ctx.clearRect(0, 0, cavW, cavH);for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来this.drawCle(this.arr[i].x, this.arr[i].y);}this.drawPoint();// 每帧画圆心this.drawLine(po , this.lastPoint);// 每帧画轨迹for (var i = 0 ; i < this.restPoint.length ; i++) {if (Math.abs(po.x - this.restPoint[i].x) < this.r && Math.abs(po.y - this.restPoint[i].y) < this.r) {this.drawPoint();this.lastPoint.push(this.restPoint[i]);this.restPoint.splice(i, 1);break;}}}wxlocker.prototype.checkPass = function(psw1, psw2) {// 检测密码var p1 = '',p2 = '';for (var i = 0 ; i < psw1.length ; i++) {p1 += psw1[i].index + psw1[i].index;}for (var i = 0 ; i < psw2.length ; i++) {p2 += psw2[i].index + psw2[i].index;}return p1 === p2;}wxlocker.prototype.storePass = function(psw,cb) {// touchend结束之后对密码和状态的处理if (this.pswObj.step == 1) {//step==1表示还没有设置密码状态if (this.checkPass(this.pswObj.fpassword, psw)) {this.pswObj.step = 2;this.pswObj.spassword = psw;this.resetHidden = false;this.title = "密码保存成功";this.titleColor = "succ";this.drawStatusPoint('#09bb07');wx.setStorageSync('passwordxx', JSON.stringify(this.pswObj.spassword));// wx.setStorageSync('chooseType', this.chooseType);} else {this.title = "两次绘制不一致,重新绘制";this.titleColor = "error";this.drawStatusPoint('#e64340');delete this.pswObj.step;}} else if (this.pswObj.step == 2) {if (this.checkPass(this.pswObj.spassword, psw)) {this.title = "解锁成功";this.titleColor = "succ";this.drawStatusPoint('#09bb07');cb();} else {this.title = "解锁失败";this.titleColor = "error";this.drawStatusPoint('#e64340');}} else {if(this.lastPoint.length<4){this.title="密码过于简单,请至少连接4个点";this.resetHidden = true;this.titleColor = "error";return false;}else{this.pswObj.step = 1;this.pswObj.fpassword = psw;this.titleColor = "";this.title = "再次输入";}}}wxlocker.prototype.makeState = function() {if (this.pswObj.step == 2) {this.resetHidden = false;this.title = "请解锁";this.titleColor = "";} else if (this.pswObj.step == 1) {this.title="请设置手势密码";this.resetHidden = true;this.titleColor = "";} else {this.title="请设置手势密码";this.resetHidden = true;this.titleColor = "";}}wxlocker.prototype.updatePassword = function(){//点击重置按钮,重置密码wx.removeStorageSync("passwordxx");// wx.removeStorageSync("chooseType");this.pswObj = {};this.title="请设置手势密码";this.resetHidden = true;this.titleColor = "";this.reset();}wxlocker.prototype.init = function() {//初始化锁盘this.pswObj = wx.getStorageSync('passwordxx') ? {step: 2,spassword: JSON.parse(wx.getStorageSync('passwordxx'))} : {};this.lastPoint = [];//记录手指经过的圆圈this.makeState();this.touchFlag = false;this.ctx = wx.createContext();//创建画布this.createCircle();//画圆圈}wxlocker.prototype.reset = function() {this.createCircle();}//适配不同屏幕大小的canvaswxlocker.prototype.setCanvasSize = function(){var size={};try {var res = wx.getSystemInfoSync();var scale = 750/686;//不同屏幕下canvas的适配比例;设计稿是750宽var width = res.windowWidth/scale;var height = width;//canvas画布为正方形size.w = width;size.h = height;} catch (e) {// Do something when catch errorconsole.log("获取设备信息失败"+e);} return size;}wxlocker.prototype.bindtouchstart = function(e){if(e.touches.length==1){var self = this;var po = self.getPosition(e);for (var i = 0 ; i < self.arr.length ; i++) {//判断手指触摸点是否在圆圈内if (Math.abs(po.x - self.arr[i].x) < self.r && Math.abs(po.y - self.arr[i].y) < self.r) {self.touchFlag = true;self.drawPoint();self.lastPoint.push(self.arr[i]);self.restPoint.splice(i,1);break;}}}wx.drawCanvas({canvasId: "locker",actions: this.ctx.getActions(),reserve:true});}