全网唯一正确身份证和社统一社会信用代码自定义表单校验器(身份证校验和社统一社会信用代码校验)
话不多说,直入正题:
1、工具类:
import * as moment from 'moment';
import {isUndefined} from 'util';
import {AbstractControl, ValidatorFn} from '@angular/forms';/*** Created by yanchao lcj on 2020/06/28.*/
export class StringUtils {constructor() {}/*** 判断是空字符串?* @param str*/static isBlank(str: string) {return isUndefined(str) || str === null || '' === str.trim();}/*** 去空格* @param str 处理字符串* @return 结果字符串*/static trim(str: string) {return str.replace('\n', '').replace(' ', '').trim();}/*** 判断不是空字符串?* @param str*/static isNotBlank(str: string) {return !this.isBlank(str);}/*** 判断是空?* @param o*/static isEmpty(o) {return o === null || o === 'null' || o === undefined || o === 'undefined' || o === '';}/*** 判断不是空?* @param o*/static isNotEmpty(o) {return !this.isEmpty(o);}/*** 校验身份证的* @param code*/public static identityCodeValid(code): ProcessResult { // 判断是否为空 长度是否合法if (this.isBlank(code) || code.length !== 18) {return new ProcessResult(false, '身份证长度不够');}code = this.trim(code);// 身份证号格式错误if (!code || !/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(code)) {return new ProcessResult(false, '身份证不合法');}// 省份对应的省编码const city = {11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江', 31: '上海',32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北', 43: '湖南',44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏', 61: '陕西',62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门', 91: '国外'};if (!city[code.substr(0, 2)]) {// 地址编码错误return new ProcessResult(false, '身份证前2为输入有误');} else {// 18位身份证需要验证最后一位校验位code = code.split('');// 身份证最后一位const lastOneCode = code[17];// 加权因子 ∑(ai×Wi)(mod 11)const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];// 校验位const parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];let sum = 0;let ai = 0;let wi = 0;// 取前17位,(每一位数字 * 每一位数字在加权因子数组的对应的数字) 之和for (let i = 0; i < 17; i++) {ai = code[i];wi = factor[i];sum += ai * wi;}// 算出来的和 mod 11 得到 最后一位,再把传进来的身份证的最后一位和算出来的最后一位对比return new ProcessResult(parity[sum % 11] === lastOneCode, '身份证不合法');}}/*** 身份证自定义校验器*/public static idCardNoValidator(): ValidatorFn {return (control: AbstractControl): { [key: string]: any } | null => {const processResult = this.identityCodeValid(control.value);return processResult.isSuccess() ? null : {idCardError: {value: control.value, message: processResult.errorMessage}};};}/*** 统一社会信用代码自定义校验器*/public static unifiedCreditCodeValidator(): ValidatorFn {return (control: AbstractControl): { [key: string]: any } | null => {const processResult = this.checkUnifiedCreditCode(control.value);return processResult.isSuccess() ? null : {unifiedCreditCodeError: {value: control.value, message: processResult.errorMessage}};};}/*** 统一社会信用代码校验* @param uniCode*/public static checkUnifiedCreditCode(uniCode: string): ProcessResult { // 假如不是18位,错误if (!uniCode || uniCode.length !== 18) {return new ProcessResult(false, '统一社会信用代码长度不合法');}uniCode = this.trim(uniCode);// 统一社会信用代码由18位阿拉伯数字或英文大写字母表示(不包括I,O,Z,S,V以防止和阿拉伯字母混淆)-->V:???关我毛事?const upUniCode = uniCode.toUpperCase();if (upUniCode.indexOf('I') !== -1 || upUniCode.indexOf('O') !== -1 || upUniCode.indexOf('Z') !== -1 || upUniCode.indexOf('S') !== -1 || upUniCode.indexOf('V') !== -1) {return new ProcessResult(false, '统一社会信用代码不能含有(I,O,Z,S,V)');}// (组织机构代码)校验const orgCheckCode = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T','U', 'V', 'W', 'X', 'Y', 'Z'];// 组织机构代码加权因子const orgWeight = [3, 7, 9, 10, 5, 8, 4, 2];const orgCode = uniCode.substr(8, 9);let sumOrg = 0;// 去前8位数 每一位数对应在orgWeight数组的下标 * 对应的加权因子 之和for (let i = 0; i < 8; i++) {const tmpAttr = orgCode[i] as any;const tmpCode = orgCheckCode.indexOf(tmpAttr);const tmpWeight = orgWeight[i];sumOrg += (tmpCode * tmpWeight);}// 再用11 - 算出的合数 mod 11const modOrg = 11 - sumOrg % 11;// 再用算出来的数字转换成最后一位的数字 拿到最后一个字符const modOrgLast = (modOrg === 10) ? 'X' : ((modOrg === 11) ? '0' : ('' + modOrg));// 对比算出来的最后一位是否等于给我的组织机构代码的最后一位if (modOrgLast !== orgCode[8]) {return new ProcessResult(false, '统一社会信用代码中的组织机构代码不合法');}// 最后一位的校验 (A=10, B=11,以此类推)const uniCheckCode = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q','R', 'T', 'U', 'W', 'X', 'Y'];// 统一社会信用代码加权因子const uniCodeWeight = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];let sumUniCode = 0;// 去前17位数 每一位数对应在uniCheckCode数组的下标 * 对应的加权因子 之和for (let i = 0; i < 17; i++) {const tmpAttr = uniCode[i] as any;const tmpCode = uniCheckCode.indexOf(tmpAttr);const tmpWeight = uniCodeWeight[i];sumUniCode += (tmpCode * tmpWeight);}// 再用31 - 算出的合数 mod 31const modOrgUni = 31 - sumUniCode % 31;// 在uniCheckCode数组找出对应的字符就是最后一位const modOrgUniLast = uniCheckCode[modOrgUni % 31];// 对比算出来的最后一位是否等于给我的信用代码的最后一位return new ProcessResult(modOrgUniLast + '' === uniCode[17] + '', '统一社会信用代码不合法');}/*** 根据身份证号码获取生日年龄性别*/public static getIdCardInformation(idCardNo): IdCardInformation {const processResult = this.identityCodeValid(idCardNo);if (processResult.isFailure()) {return new IdCardInformation(undefined, undefined, undefined);}// 区分二代身份证const mark = idCardNo.length > 15;// 获取身份证上的出生日期const birthday = moment(idCardNo.substring(6, mark ? 14 : 11), 'YYYYMMDD').toDate();// 算出年龄const age = new Date().getFullYear() - birthday.getFullYear();// 得出年龄const gender = !(Number(idCardNo.charAt(mark ? 16 : 14)) % 2 === 0);// 返回身份证信息return new IdCardInformation(birthday, age, gender);}
}/*** 身份证信息*/
class IdCardInformation {/*** 出生日期*/birthday: Date;/*** 年龄*/age: number;/*** 性别*/gender: boolean;constructor(birthday: Date, age: number, gender: boolean) {this.birthday = birthday;this.age = age;this.gender = gender;}
}/*** 处理结果*/
class ProcessResult {/*** 成功?*/success: boolean;/*** 错误信息*/errorMessage: string;constructor(success: boolean, errorMessage: string) {this.success = success;this.errorMessage = errorMessage;}/*** 是成功的?*/isSuccess() {return this.success;}/*** 是失败的?*/isFailure() {return !this.success;}
}
2、表单对象 :
this.formGroup = this.fb.group({// 证件号码idCard: [null, [Validators.required, StringUtils.idCardNoValidator()]]
});
3、页面用管道显示错误信息:
<nz-form-item><nz-form-label [nzSm]="4" [nzXs]="12" nzRequired>证件号码</nz-form-label><nz-form-control [nzValidateStatus]="formGroup.get('idCard')"nzHasFeedback [nzErrorTip]="formGroup.get('idCard').errors | errorMessage"[nzSm]="7" [nzXs]="12"><input nz-input formControlName="idCard" placeholder="请输入证件号码"/></nz-form-control>
</nz-form-item>
4、管道的类:
import {Pipe, PipeTransform} from '@angular/core';
import {ValidationErrors} from '@angular/forms';@Pipe({name: 'errorMessage'
})
export class ErrorMessagePipe implements PipeTransform {constructor() {}errors: ValidationErrors;formatError(key) {switch (key) {case 'required':return '必填项';case 'idCardError':return this.errors[key].message;case 'unifiedCreditCodeError':return this.errors[key].message;default:return '';}}transform(errors: ValidationErrors): any {this.errors = errors;// tslint:disable-next-line:forinfor (const key in errors) {return this.formatError(key);}}}
效果:
5、校验身份证获取身份证信息:
const value = "身份证号码";// 获取身份证里面的信息如:出生日期 年龄 性别 当然还可以获得出生地,这里我没实现
const idCardInformation = StringUtils.getIdCardInformation(value);// 身份证校验
const success = StringUtils.identityCodeValid(value).isSuccess();// 统一社会信用代码校验
const success1 = StringUtils.checkUnifiedCreditCode(‘****’).isSuccess();
全网唯一正确身份证和社统一社会信用代码自定义表单校验器(身份证校验和社统一社会信用代码校验)相关推荐
- 记录element-ui自定义表单验证上传身份证正反面
大概是这个样式 两个上传组件写在一个form-item里进行自定义表单验证 每次验证,通过判断上传组件绑定的值进行判断,callback不同的提示错误 <template><div& ...
- element自定义表单验证上传身份证正反面的实现
效果图 <template> <div> <el-form :model="personalForm" :rules=&quo ...
- layui前端表单验证(身份证,手机号 图形验证码等)
文章目录 前言 一.layui前端验证 二.使用步骤 1.以下介绍几个常用的前端验证 2.thinkphp后台验证 3.效果展示 前言 layui前端框架是一款比较流行的前端框架,多模块集成的UI框架 ...
- ant-design表单验证手机号身份证号
<Form.Itemlabel="电话"name="phone"rules={[{required: true, message: '请输入电话', ma ...
- 达梦8数据库更新语句包含单引号双引号引起转义字符执行失败解决方法全网唯一
达梦数据库更新语句包含单引号双引号引起执行失败解决方法全网唯一 如果一个更新的UPDATE更新语句的内容包含单引号',会引起执行错误! 错误的类型不止这一种,但是都是因为内容里面包含转义字符单引号引起 ...
- html5表单pattern属性配合正则验证手机号码,身份证
pattern="[1]+[3456789]+\d{9}" html5表单自带的表单验证规则身份证,手机号 html5表单验证 之前一直不知道怎么自定义提示信息,今天看到了资料就记 ...
- JS常用的表单验证(数字、长度,汉字,邮箱,手机号,身份证等)
1.英文字母 >>jsp,html语句 <input type="text" οnblur="checkChart(this.value)" ...
- element-ui表单验证(验证手机号是否正确,自定义验证规则)
效果图 1. html <el-form :model="userForm"status-icon:rules="rules"class="lo ...
- vue中如何进行身份证合法性校验(身份证18位,包含最后一位数字/字母)
文章目录 前言 正文 1. 首先,根据实际情况,目前我们使用的身份证由18位构成,包括数字和字母X.那么,在input输入框中就需要限制用户输入的数据类型. 2.其次,查看Element ui 组件库 ...
最新文章
- 初学者的机器学习入门实战教程!
- Linux CentOS下如何确认MySQL服务已经启动
- 软件测试 学习之路 html基础
- 画面设置_LOL手游设置界面翻译:基本设置/画面/音效/功能与快捷语音
- .net core webapi 导出excel(两种方式EPPLUS、NPOI),返回下载地址或文件流
- HTML关联两个标签事件,javascript – 交换2个html元素并保留事件侦听器
- mysql怎么下载_mysql下载安装使用教程
- 百度搜索跳过验证码_百度搜索是死是活?网友吵翻了天,你觉得呢
- 迅捷图片格式转换器v1.00.1中文免费版
- python实时语音转写_语音识别 - 实时语音转写 - 《科大讯飞REST_API开发指南》 - 书栈网 · BookStack...
- vue 左侧菜单可拖动
- 变速精灵试用 目前唯一支持Vista加速
- matlab读取hdf显示,matlab读取hdf
- 基于SONY CCD ICX285的成像电路设计
- JAVA基础之类和对象
- clipboard剪切板
- 安装好maya后运行不了并弹出如图的错误
- 精确到秒!一位清华学霸的学习生活计划表,值得借鉴!
- 普宁市中学高考成绩查询2021,2021年中山高考状元多少分是谁,中山高考状元名单资料...
- 关系模型知识点总结(3)—— 关系操作中的关系代数(含题目及详细分析)
热门文章
- String 翻转字符串
- datagridview 显示红色叉_显示器促销日常数码店招首页装修PSD模板分层psd素材
- 计算机cpu特点,电脑CPU性能怎么看
- 使用office2007打开excel报错:不是有效的win32文件
- ltunes无法验证服务器,itunes无法验证服务器身份
- Type error: Too few arguments to function Illuminate\Support\Manager::createDriver()
- 基于Springboot框架的登录注册页面
- 盛华软件工作室 -开张了
- 《计量地理学》实习指南
- eclipse中包里建包