看不惯各种信息收集表,我手写了一个身份证号输入组件

简介: `shigen`是一位专注于Java、Python、Vue和Shell等技术的博主,分享知识和成长经历。为应对需频繁输入身份证号码的情况,`shigen`决定研究身份证校验机制。研究过程中,了解到身份证号码的生成规则,包括18位数字及校验码计算。通过编写JavaScript代码,实现了两个级别的身份证号码验证:一级仅检查基本格式,二级则加入校验码计算,确保符合生成规则。代码示例展示了逐步增强的验证功能,防止随意修改身份证号码。欢迎交流讨论,共同进步!

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。
个人IP:shigen

背景

shigen最近的需要填写各种报名表的场景有点多,很多场景都要输入身份证号。对于这些信息,我特别的敏感,所以,我想着能糊弄过去就糊弄过去。之前也确实有乱填,只要凑够了18位,或者我随意改动身份证上的某一位数字就行了。但是,直到我遇到了一种表单:我改一个数字,它发现了,不让我提交!我气急败坏,我要研究一下这玩意怎么实现的。总不至于调用了某云的身份证地址库吧。

于是一个早晨,我就开始坐在了电脑前,研究起这个了。

申明:测试ID来自于互联网,关键信息我也会进行打码,并无实际的数据价值。

研究

身份证号18位,毋庸置疑。够了18位这是基础,完了就是它的生成规则。我特意的查阅了资料:中华人民共和国居民身份证

身份证编排

反正就是一套规则约束,最后一位校验码通过运算出来的。

原理懂了,那就要开始写代码验证了。为此,我在互联网上找到了一个身份证号,用于实际的测试验证:

身份证ID

代码设计

身份证号的输入,我选用设计一个通用的组件来完成,实现它的灵活性。

level 0ne

第一层次的,我们不引入任何的算法,只对身份证号的规则进行一次校验,这也是很多网站存在的问题。

分装组件
<template>
  <el-form-item :label="label" :prop="prop" :rules="rules">
    <el-input v-model="idNumber" @input="checkIdNumber" :placeholder="placeholder" clearable />
  </el-form-item>
</template>

<script>
export default {
   
   
  props: {
   
   
    label: String,
    prop: String,
    // 父组件的表单实例
    parentFormRef: Object,
    placeholder: {
   
   
      type: String,
      default: ''
    },
    value: {
   
   
      type: String,
      default: ''
    }
  },
  data() {
   
   
    return {
   
   
      idNumber: this.value,
      rules: [
        {
   
   
          validator: this.validateIdNumber,
          trigger: 'blur'
        }
      ]
    };
  },
  watch: {
   
   
    value(newValue) {
   
   
      this.idNumber = newValue;
    }
  },
  methods: {
   
   
    validateIdNumber(rule, value, callback) {
   
   
      if (!value) {
   
   
        callback(new Error('请输入身份证号码'));
      } else if (!this.check(value)) {
   
   
        callback(new Error('请输入有效的身份证号码'));
      } else {
   
   
        callback();
      }
    },
    checkIdNumber() {
   
   
      this.$nextTick(() => {
   
   
        // 确保在下一次 DOM 更新周期后再访问父组件传递的表单实例
        if (this.parentFormRef) {
   
   
          this.parentFormRef.validateField('idNumber');
        }
      });
      // 将输入的值通过 input 事件传递给父组件
      this.$emit('input', this.idNumber);
    },
    check(value) {
   
   
      const pattern = /^[1-9]\d{5}(18|19|20)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}([0-9]|X|x)$/;
      return pattern.test(value);
    },
  }
};
</script>

看起来内容小多,关键的逻辑还是对于身份证号的验证,这里选用的是正则表达式。别的就是一些自定义传值的约束和定义。

设计的时候,踩了很多的坑,具体的注意点写在了注释里。

页面使用

在页面中,我们需要这样使用:

<template>
  <div>
    <el-form :model="info" ref="myForm">
      <id-number-input v-model="info.idNumber" :parentFormRef="myForm" label="身份证号码" prop="idNumber"
        placeholder="请输入身份证号码" />
    </el-form>
    <p>idNumber: {
   
   {
   
    info.idNumber }}</p>
    <el-button type="primary" @click="submitForm">提交</el-button>
  </div>
</template>

<script>
import IdNumberInput from '@/components/IdNumberInput.vue';

export default {
   
   
  components: {
   
   
    IdNumberInput
  },
  data() {
   
   
    return {
   
   
      info: {
   
   
        idNumber: '',
      },
      myForm: null,

    };
  },
  methods: {
   
   
    submitForm() {
   
   
      this.$refs.myForm.validate((valid) => {
   
   
        if (valid) {
   
   
          // 表单验证通过,执行提交逻辑
          this.$message.success('表单验证通过,执行提交逻辑');
        } else {
   
   
          // 表单验证不通过
          this.$message.error('表单验证不通过');
        }
      });
    },
  }
};
</script>

如此,简单的第一步完成,看看效果:

测试效果

修改出生年月日或者后四位数字的任何一位,照样可以现实验证通过。

level Two

在上一步的基础上,引入了新的校验生成规则;参考了文章身份证号规则校验最全总结

check2(value) {
   
   
  let idcode = value;

  if (!this.check(idcode)) return false;

  // 加权因子
  const weightFactor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  // 校验码
  const checkCode = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

  const code = String(idcode);
  const last = idcode[17]// 最后一位

  const seventeen = code.substring(0, 17);

  // ISO 7064:1983.MOD 11-2 判断最后一位校验码是否正确
  const arr = seventeen.split('');
  const len = arr.length;
  let num = 0;
  for (let i = 0; i < len; i++) {
   
   
    num = num + arr[i] * weightFactor[i];
  }

  // 获取余数
  const resisue = num % 11;
  const lastNo = checkCode[resisue];
  return last === lastNo;
},

这种方式就是引入了生成规则的校验,这次,随意修改不行了。

修改后验证结果

以上就是整个探秘+揭秘的整个过程,欢迎评论交流。

与shigen一起,每天不一样!

目录
相关文章
|
2月前
创建逻辑表单,信息收集更智能
设置显隐规则,可以实现 选择不同选项显示不同内容 的效果。适用于问卷、评价或巡检巡查场景使用,一份表单,得到两种甚至多种反馈。
|
4月前
|
SQL 前端开发 Java
若依修改03----利用若依代码生成器,生成课程管理的前后端代码,课程的条件搜索接口,一旦数据表创建好了,直接交给若依代码的生成器就好了,配置代码生成信息,包含基本信息,字段信息,生成信息。字段信息决
若依修改03----利用若依代码生成器,生成课程管理的前后端代码,课程的条件搜索接口,一旦数据表创建好了,直接交给若依代码的生成器就好了,配置代码生成信息,包含基本信息,字段信息,生成信息。字段信息决
|
XML 数据格式
FastReport自动提取表的逻辑
FastReport自动提取表的逻辑
|
JSON 前端开发 Java
基于Springboot外卖系统16:菜品修改模块+菜品信息回显+ID查询口味列表+组装数据并返回
在菜品管理列表页面点击修改按钮,跳转到修改菜品页面,在修改页面回显菜品相关信息并进行修改,最后点击确定按钮完成修改操作。
213 0
分组分类的查询与保存
分组分类的查询与保存
160 0
分组分类的查询与保存
|
数据安全/隐私保护 C语言
【C语言】制作“学生管理成绩系统”,内容包括【系统显示】【录入信息】【删除信息】【等级评定】【成绩排序】【成绩修改】【查找学生】涉及循环、结构体和数组等
学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢? 导言 学生菜单系统是基于前阶段的C语言学习,从实际出发,巩固C语言基础的练习,通过多种函数的不同运用,检验知识点的牢固可靠性。 系统设计概述 整个学生系统将会被分成几个内容,将大任务分为多个小任务,并将其合理连接起来,独立而又有联系,对逻辑能力有一定要求(没错,我是木头) 设计多个模块 开发团队信息(即首
【C语言】制作“学生管理成绩系统”,内容包括【系统显示】【录入信息】【删除信息】【等级评定】【成绩排序】【成绩修改】【查找学生】涉及循环、结构体和数组等
|
存储 Android开发
方法:一键把一堆手机号码一次性快速导入手机通讯录
手机是人们日常沟通常用的工具,所以自然就要用到手机里面的通讯录联系。因此我们常要把别人的号码存入到手机通讯录里面,如果只是存五个十个那就动动手指就可以了。但是如果你想存把一个电脑excel表格里面的几百个、几千个、几万个等数量级别的联系人一键导入手机通讯录,显然手动一个个来存入是不现实的。我这里演示,通过借助网上常见的便捷工具软件,金芝号码提取导入助手,代替你手动工作来快速完成这个工作,如何一键把一堆手机号码一次性快速导入手机通讯录,省事省时省力。下面做个操作过程的图文讲解。
3840 0
方法:一键把一堆手机号码一次性快速导入手机通讯录
|
Java 数据安全/隐私保护 开发者
【实验】-员工列表-公共页抽取|学习笔记
快速学习【实验】-员工列表-公共页抽取
|
Java 关系型数据库 MySQL
使用所学Spring知识,实现简易的图书查询系统功能。实现查询全部图书。 根据书籍编号查询信息。 根据书名查询书籍信息。 根据状态查询书籍信息。
使用所学Spring知识,实现简易的图书查询系统功能。实现查询全部图书。 根据书籍编号查询信息。 根据书名查询书籍信息。 根据状态查询书籍信息。
267 0
使用所学Spring知识,实现简易的图书查询系统功能。实现查询全部图书。 根据书籍编号查询信息。 根据书名查询书籍信息。 根据状态查询书籍信息。