基于Flutter实现手势密码加密与解锁功能

目录
  • 前言
  • 1、绘制静态图形
  • 2、存储手势密码数据
  • 3、添加手势交互
  • 4、绘制、刷新密码线
  • 5、加入密码错误动画
  • 总结

前言

密码的由来:在公元前405年,由古希腊和斯巴达的战争中,由于斯巴达盟友波斯帝国背叛,导致古希腊和斯巴达两败俱伤,这时斯巴达抓了一个波斯国的信使,这个信使 没有任何情报,只有一条有着杂乱无章的希腊字母的普通腰带,最终斯巴达统帅破解了这条腰带,成功击败了希腊。这就是世界上最早的密码。同时也是世界上最早的解密。

密码在我们生活中无处不在,作为个人隐私的最后一道防线显得无比的重要,现在世界有各种各样形形色色的密码,解密方式也是层出不穷,加密,解密的过程里充满了数学以及计算机的知识,而现在手机的加密的方式也有很多、数字、手势、指纹、人脸、虹膜等等方式多种多样,有加密就有解密、有破译等等,有些App为了安全起见,例如招商银行的银行类的App在每次启动的时候都需要解锁验证身份,那么今天我们用Flutter实现一个其中的加密方式,手势密码。

知识点:手势识别、绘制、动画

1、绘制静态图形

手势密码一般都是九宫格的形状,所以第一步我们先把这个辅助矩形九宫格画出来,然后在每一个格子内就可以绘制我们喜欢的图形了,九宫格那就很简单了。
首先我们定义一个正方形300*300 为九宫格的区域,然后对这个正方形平均分成9个小格子,我们需要找到这9个小格子的中心点来绘制九宫格,那么我们找到之后把每个小格子的中心用一个List存储起来方便以后绘制。

代码:

double size = 300;// 正方形边长
List<Offset> centerOffset = <Offset>[];// 九宫格中心点

// 上面3个
centerOffset.add(Offset(-size / 3, -size / 3));
centerOffset.add(Offset(-size / 3 + size / 3, -size / 3));
centerOffset.add(Offset(-size / 3 + size / 3 * 2, -size / 3));

// 中间3个
centerOffset.add(Offset(-size / 3, 0));
centerOffset.add(Offset(-size / 3 + size / 3, 0));
centerOffset.add(Offset(-size / 3 + size / 3 * 2, 0));

// 下面3个
centerOffset.add(Offset(-size / 3, size / 3));
centerOffset.add(Offset(-size / 3 + size / 3, size / 3));
centerOffset.add(Offset(-size / 3 + size / 3 * 2, size / 3));

接下来我们就可以用这些点绘制九宫格了。

核心代码:

Paint paint = Paint()
  ..style = PaintingStyle.stroke
  ..strokeWidth = 2
  ..color = Colors.black87;

canvas.drawRect(
    Rect.fromCenter(center: Offset.zero, width: 300, height: 300), paint);

// 绘制辅助区域
_drawHelpRect(canvas, size, paint);
void _drawHelpRect(Canvas canvas, Size size, Paint paint) {
  for (int i = 0; i < centerOffset.length; i++) {
    canvas.drawRect(
        Rect.fromCenter(center: centerOffset[i], width: 100, height: 100),
        paint);
  }
}

效果图:

得到九宫格之后,我们看到很多手势解锁小格子内都是圆形,这里我们继续在每个小格子绘制圆形图案,

核心代码:

// 绘制圆
_drawCirCle(canvas, size, paint);
void _drawCirCle(Canvas canvas, Size size, Paint paint) {
 for (int i = 0; i < centerOffset.length; i++) {
   canvas.drawCircle(centerOffset[i], 30, paint..color = Colors.black87);
 }
}

效果图:

到这里基本图形已经绘制完了。

2、存储手势密码数据

首先我们看下手势解锁一共有按下、移动、抬起三个动作组成,在移动的过程中会经过九宫格内部的圆形区域,也就是说,在经过圆形区域的时候,我们需要将这个数据保存下来然后通知画布进行更新,这里的逻辑跟我之前一篇绘制海豚那篇原理一样,首先创建UnlockController类继承ChangeNotifier。这里我们将九宫格中的每一个小格子对应一个数字进行封装一下。也是之后的设置和解锁需要保存的数据。 这样的话我们上面的九宫格就需要修改一下了,将Offset改为PassWord就行。

数据代码:

class UnlockController extends ChangeNotifier {
  // 存储按压的点集合
  List<PassWord> _points = [];

  List<PassWord> get points => _points;

  // 当前手指的位置
  Offset? _currentOffset;

  Offset? get currentOffset => _currentOffset;

  //
  set currentOffset(Offset? value) {
    _currentOffset = value;
    notifyListeners();
  }

  addPoint(PassWord offset) {
    _points.add(offset);
    notifyListeners();
  }

  // 清除所有点
  clearAllPoint() {
    _points.clear();
    notifyListeners();
  }
}

class PassWord {
  int num; // 密码数字
  Offset offset; // 密码数字对应的点
  PassWord(this.num, this.offset);
}

有了这些数据之后我们接下来就要跟手势进行交互了。

3、添加手势交互

接着上面刚说的,交互一共有三种状态,按下、移动、抬起,那么我们就先对这三种状态进行监听,

GestureDetector(
  child: CustomPaint(
    size: Size(size, size),
    painter:
        _GesturesUnlockPainter(_unlockController, centerOffset),
  ),
  onPanDown: (d) {
    // 手指按下
},
  onPanUpdate: (d) {
    // 移动
  },
  onPanEnd: (d) {
   // 抬起结束
  },
)

交互思路: 手势密码的特点是每个九宫格只允许点亮一次,再次经过不保存数据。

按下: 判断是否在九宫格内部任一圆形区域内,在:点亮圆形,保存数据,不在:不做任何操作,

移动: 判断是否移动到九宫格任一圆形区域内,在:判断是否已点亮-未点亮:点亮圆形,保存数据,已点亮:不做任何操作,不在区域内,也不做数据任何操作。

抬起: 获取密码,进行设置或验证。

大概思路还是比较清晰的,下面我们就对这些判断条件进行判断。

代码:

///手指按下、移动触发
void judgeZone(Offset src) {
  /// 循环所有的九宫格
  for (int i = 0; i < centerOffset.length; i++) {
    var srcTranslate = src.translate(-size / 2, -size / 2);
    // 判断手指按的位置是否在九宫格圆形区域
    if (judgeCircleArea(srcTranslate, centerOffset[i].offset, 30)) {
      // 在 判断是否已添加
      for (int j = 0; j < _unlockController.points.length; j++) {
        if (_unlockController.points[j] == centerOffset[i]) {
          // 已添加过 返回
          return;
        }
      }
      // 未添加过 进行添加
      _unlockController.addPoint(centerOffset[i]);
      return;
    }
  }
  // 无点
}
///判断出是否在某点的半径为r圆范围内
bool judgeCircleArea(Offset src, Offset dst, double r)=>(src - dst).distance <= r;

有了手指数据之后,我们就能根据这些数据的变化进而通知画布进行更新了。

4、绘制、刷新密码线

上面我们已经拿到数据了,接下来我们进行绘制密码线,如何刷新画布之前的文章我已经讲过很多遍了,这里不熟悉的同学可以看下之前绘制小海豚那一篇文章贝塞尔曲线绘制一个小海豚,回归正题,既然我们拿到了手指经过的九宫格的中心点,那绘制线就变得非常容易了,

核心代码:

var offsets = unlockController.points.map((e) => e.offset).toList();
// 绘制按压点
canvas.drawPoints(
    PointMode.points,
    offsets,
    paint
      ..strokeWidth = 20
      ..strokeCap = StrokeCap.round
      ..color = Colors.red);
// 绘制密码
Path path = Path();
if (unlockController.points.isNotEmpty) {
  path.moveTo(unlockController.points[0].offset.dx,
      unlockController.points[0].offset.dy);
  if (unlockController.currentOffset != null) {
  // 绘制当前手势线 未经过九宫格圆形时
    canvas.drawLine(unlockController.points.last.offset,
        unlockController.currentOffset!, paint..strokeWidth = 2);
  }
}
for (int i = 1; i < unlockController.points.length; i++) {
  path.lineTo(unlockController.points[i].offset.dx,
      unlockController.points[i].offset.dy);
}
canvas.drawPath(path, paint..strokeWidth = 2);

这样我们就把手势经过的密码线绘制出来了。

效果图:

5、加入密码错误动画

当我们输入密码错误时,给用户一个提示密码错误的交互也是很有必要的,那么接下来我们就添加一个简单文字抖动效果提示用户密码输入错误。
添加动画也很简单,思路: 不断改变文字的边距从而达到抖动效果。

核心代码:

late AnimationController _animationController =
    AnimationController(vsync: this, duration: Duration(milliseconds: 500));

late CurvedAnimation curvedAnimation =
    CurvedAnimation(curve: Curves.easeIn, parent: _animationController);
late Animation<double> animation =
    Tween(begin: 0.0, end: 10.0).animate(curvedAnimation)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          _animationController.reset();
        }
      });
AnimatedBuilder(
    animation: animation,
    builder: (ctx, child) {
      return Container(
        margin: EdgeInsetsDirectional.only(
            bottom: 20,
            start: _errorPwd() * 20,
            end: animation.value),
        child: Text(
          text,
          style: TextStyle(fontSize: 20, color: textColor),
        ),
      );
    }),

double _errorPwd() {
  double x = animation.value; // 变化速度 0-10,
  double d = x - x.truncate(); // 获取这个数字的小数部分
  double? y;
  if (d <= 0.5) {
    y = 2 * d;
  } else {
    y = 1 - 2 * (d - 0.5);
  }
  return y;
}

假设我们设置的密码是14789,也就是L型,看下最终效果:

完整源码之后我会放到github上。

总结

通过手势识别我们用到了App中核心的三大框架,手势、绘制、以及动画中的知识。其实原理也并不复杂,只要掌握了这三大框架的核心基础知识

到此这篇关于基于Flutter实现手势密码加密与解锁功能的文章就介绍到这了,更多相关Flutter手势密码加密解锁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android实现支付宝手势密码功能

    今天就给大家分享android实现支付宝手势密码,很常见,像现在用微信支付,支付宝支付的时候都要自己设置的4位PIN码,然后输入PIN码后立即调用支付接口去支付,毫无疑问的安全问题,不会觉得手机被人拿了后却不知道自己网银的钱的去向,这也是正常安全逻辑性问题. 好,下面我们来看下具体的实现: 入口,启动页面就简单的几个按钮,布局贴出来,代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android

  • Android自定义View九宫格手势密码解锁

    由于公司新的项目需要用到九宫格手势密码解锁的功能,于是觉得自己写一个.废话不多说,直接上效果图: 首选我们来分析下实现的思路: 1. 绘制出相对于这个View的居中的九个点,作为默认状态的点 2. 点击屏幕的时候是否点击在这九个点上 3. 在屏幕上滑动的时候,绘制两个点之间的线条,以及选中状态的点 4. 手指离开屏幕的时候判断手势密码是否正确,如若错误这把错误状态下的点和线绘制出来. 具体实现: 首先我们得绘制出默认正常状态下的九个点: /** * 点的bean * Created by Adm

  • Flutter手势密码的实现示例(附demo)

    目录 前言 开始 绘制圆点 绘制手势路径 组合9个圆点盘和手势路径 手势密码组件的使用 上传自定义组件到pub仓库 后记 前言 本篇记录的是使用Flutter完成手势密码的功能,大致效果如下图所示: 该手势密码的功能比较简单,下面会详细记录实现的过程,另外还会简单说明如何将该手势密码作为插件发布到pub仓库. 开始 实现上面的手势密码并不难,大致可以拆分成如下几部分来完成: 绘制9个圆点 绘制手指滑动的线路 合并以上两个部分 绘制圆点 我们使用面向对象的方式来处理9个圆点的绘制,每个圆点作为一个

  • Android手势密码实现实例代码

    一.效果实现 二.实现思路: 1. 正上方的提示区域,用一个类(LockIndicator.java)来实现,自定义view来绘制9个提示图标: 2. 手势密码绘制区域,用一个类(GestureContentView.java)来实现,它继承自ViewGroup里面, 添加9个ImageView来表示图标, 在onLayout()方法中设置它们的位置: 3. 手势路径绘制, 用一个类(GestureDrawline.java)来实现,复写onTouchEvent()方法,在这个方法里面监听Tou

  • Android仿支付宝手势密码解锁功能

    Starting 创建手势密码可以查看 CreateGestureActivity.java 文件. 登陆验证手势密码可以看 GestureLoginActivity.java 文件. Features 使用了 JakeWharton/butterknife butterknife 使用了 ACache 来存储手势密码 /** * 保存手势密码 */ private void saveChosenPattern(List<LockPatternView.Cell> cells) { byte[

  • 基于Flutter实现手势密码加密与解锁功能

    目录 前言 1.绘制静态图形 2.存储手势密码数据 3.添加手势交互 4.绘制.刷新密码线 5.加入密码错误动画 总结 前言 密码的由来:在公元前405年,由古希腊和斯巴达的战争中,由于斯巴达盟友波斯帝国背叛,导致古希腊和斯巴达两败俱伤,这时斯巴达抓了一个波斯国的信使,这个信使 没有任何情报,只有一条有着杂乱无章的希腊字母的普通腰带,最终斯巴达统帅破解了这条腰带,成功击败了希腊.这就是世界上最早的密码.同时也是世界上最早的解密. 密码在我们生活中无处不在,作为个人隐私的最后一道防线显得无比的重要

  • Oracle 11g用户修改密码及加锁解锁功能实例代码

    1.运行 cmd.exe: 2.输入 sqlplus / as sysdba,以系统管理员(sysdba)身份连接数据库,进行数据库管理操作. 3.连接成功后执行 alter user identityName identified by password; -–修改密码 alter user identityName account unlock; -–解锁 alter user identityName account lock; -–加锁 identityName:需要修改的用户: pas

  • Spring Security使用数据库认证及用户密码加密和解密功能

    流程图: 1.接上一篇博客https://mp.csdn.net/console/editor/html/104576494,准备好环境. 2.spring-security.xml中的配置: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="

  • jasypt 集成SpringBoot 数据库密码加密操作

    昨天看到一片文章,说是某某旗下酒店数据库因为程序员不小心,把数据库明文密码上传到了GitHub上,导致酒店数据注册资料.入住信息,开房记录被下载倒卖的消息. 作为程序员,开发的时候为了简单,账户明明都设置很简单,基本上数据库密码都是明文的,没做什么操作,至少我待过的公司都是这样,无论是测试环境还是线上环境,想想,这个也是一大安全隐患,在此,趁现在不忙,做些基于springboot的数据库密码加密. 1.pom.xml添加jar包(不同jdk选择不同的版本): <!-- jdk8 版本 整合jas

  • iOS仿邮箱大师的九宫格手势密码解锁

    本文实例为大家分享了iOS手势密码解锁的相关代码,供大家参考,具体内容如下 // // LockView.m // 手势解锁 // // Created by Daniel on 16/4/4. // Copyright © 2016年 Daniel. All rights reserved. // #import "LockView.h" @interface LockView () /** 保存已选中的按钮 */ @property(nonatomic, strong) NSMut

  • 基于C#对用户密码使用MD5加密与解密

    C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式.本文总结了通用的算法并结合了自己的一点小经验,分享给大家. 一.使用16位.32位.64位MD5方法对用户名加密 1)16位的MD5加密 /// <summary> /// 16位MD5加密 /// </summary> /// <param name="password"></param> /// <returns></returns&

  • Android自定义UI手势密码终结版

    之前写过3篇手势密码的demo,不过没有集成到真实的企业项目中,这几天正好领到一个手势密码项目,昨天刚好弄完,今天抽空整理下,目前还没有完善,有一些地方需要更改,不过基本的流程都可以跑通了. 源码下载地址:http://xiazai.jb51.net/201610/yuanma/AndroidGestureLock(jb51.net).rar 先看主界面的入口把.里面有2个button(一个是设置手势密码.一个是校验手势密码) activity_main.xml <RelativeLayout

随机推荐