如何优雅的对input框数据进行动态脱敏

简介: 🎈所谓的数据脱敏,是指在不影响数据分析结果的准确性前提下,对原始数据中的敏感字段进行处理,从而降低数据敏感度和减少个人隐私风险的技术措施。在现在这个大数据时代,个人隐私信息在互联网上传播的几率是很大的,因此作为前端工程师,我们很多时候也需要在视图层面对数据进行脱敏展示处理。## 场景

说在前面

🎈所谓的数据脱敏,是指在不影响数据分析结果的准确性前提下,对原始数据中的敏感字段进行处理,从而降低数据敏感度和减少个人隐私风险的技术措施。在现在这个大数据时代,个人隐私信息在互联网上传播的几率是很大的,因此作为前端工程师,我们很多时候也需要在视图层面对数据进行脱敏展示处理。

场景

在一个页面上,我们需要客户输入手机号码、身份证号码等敏感信息,客户要求在输入的时候可以对输入内容进行脱敏处理,同时原始数据需要保存到数据库,如下图:

image.png

脱敏格式:保留身份证号码的前四位和后六位,中间使用*号代替

体验

体验地址:http://jyeontu.xyz/JDemo

难点分析

接到需求后我们需要先对其进行简单分析,可以得出大致有以下几个问题需要处理。

  • 1、input框输入值与展示值分离;
  • 2、对展示值进行修改时,需要同步修改真实值;
  • 3、真实值与展示值同步动态转换。
  • 4、光标位置需要重设;

功能实现

想要实现该功能只需要将前面分析得出的难点一一克服,我们就可以实现该功能。

1、input框输入值与展示值分离

这个问题其实比较好解决,我们可以添加两个变量,分别保存输入的真实数据和脱敏后的展示数据。

<template>
    <div>
        <div class="form-item">身份证号码脱敏(显示前4位和后6位)</div>
        <input class="form-item" 
            v-model="showValue" 
            placeholder="请输入身份证号码"
            @input="desenInputText" 
        />
        <div class="form-item">输入数据</div>
        <div class="form-item"> {{ value }} </div>
    </div>
</template>

如上代码,我们分别使用showValue和value两个变量来保存脱敏后的展示数据和输入的真实数据。

2、对展示值进行修改时,需要同步修改真实值

我们可以给input框绑定input事件,每次输入时对真实值和展示值进行动态转换,具体转换方法后面会说到。

desenInputText(e) {
    //真实值与展示值同步动态转换
},

3、真实值与展示值同步动态转换

3.1 末尾追加 or 删除

这里是该功能真正意义上的第一个难点,我们需要同时维护两个变量的值,主要有以下四种场景:
image.png

  • 1、输入单个字符

如上图,此时的展示值为1234***891011,真实值为1234567891011,如果此时我们在最后追加一个字符2,应该需要进行怎样地处理?其实只需要两步:

(1)将输入的`2`拼接到真实值后面,此时真实值变为`12345678910112`;

(2)再对真实值进行脱敏得到展示值`1234****910112`。
  • 2、复制输入多个字符

如果此时我们并不是在最后追加一个字符,而是需要将剪切板的多个字符(如:234)追加到数据后面呢?我们需要进行以下三步操作:

(1)计算展示值和真实值之差n;

(2)将展示值的末尾n位拼接到真实值后面,此时真实值变为`1234567891011234`;

(3)再对真实值进行脱敏得到展示值`1234******011234`。
  • 3、删除单个字符

删除单个字符时我们只需要将真实值末尾的字符输出,再重新转换展示值即可。

  • 4、选中删除多个字符

删除多个值的时候,我们需要进行以下三步操作:

(1)计算展示值和真实值之差n;

(2)删除真实值的末尾n位;

(3)对真实值进行脱敏得到展示值。

3.2 非末尾插入 or 删除

前面我们看了在末尾插入或者删除的4种场景,知道了简单场景下的动态转换方法,那么将修改位置移动到字符串中间呢?暂停五分钟思考一下我们应该要怎么做?\
5\
.\
.\
.\
4\
.\
.\
.\
3\
.\
.\
.\
2\
.\
.\
.\
1\
.\
.\
.\
0\
有了大致思路了吗?我们接着往下进行:\
插入位置变了,那如果我们可以找到插入位置,我们是不是可以将插入的开始位置看成是末尾,在这个位置插入增量数据或者删除掉减量数据即可?所以我们需要进行以下四步:\

(1)获取当前光标位置ind;

(2)计算展示值和真实值之差n;

(3)在输入起始位置(ind-n+1)插入增量数据;

(4)对真实值进行脱敏得到展示值。

具体代码如下

//输入框动态脱敏
desenInputText(e) {
    const ind = e.target.selectionStart - 1;
    let value = this.value;
    const showValue = this.showValue;
    const isAdd = showValue.length > value.length;
    const num = Math.abs(value.length - showValue.length);
    if (isAdd) {
        value =
            value.slice(0, ind-num+1) +
            showValue.slice(ind-num+1,ind+1) +
            value.slice(ind-num+1);
    } else {
        value = value.slice(0, ind + 1) + value.slice(ind + num + 1);
    }
    this.value = value;
    this.showValue = this.desenText(value);
},

4、光标位置需要重设

写完上面的代码后已经可以大致实现数据动态脱敏的功能,但是试了几遍后我们会发现,每次输入后光标都会自动移动到输入框的最后面,我们还需要处理一下这个问题,将光标保持在原来的位置上。

const elem = e.target;
if (elem.setSelectionRange) {
    // 标准浏览器
    elem.setSelectionRange(ind + 1, ind + 1);
} else {
    // IE9-
    const range = elem.createTextRange();
    range.moveStart('character', ind + 1);
    range.moveEnd('character', ind + 1);
    range.select();
}

完整代码

<template>
    <div>
        <div class="form-item">身份证号码脱敏(显示前4位和后6位)</div>
        <input class="form-item" 
            v-model="showValue" 
            @input="desenInputText" 
            placeholder="请输入身份证号码"
        />
        <div class="form-item">输入数据</div>
        <div class="form-item"> {{ value }} </div>
    </div>
</template>

<script>
export default {
    name:'desensitize-input',
    data(){
        return {
            showValue:'',
            value:''
        }
    },
    methods:{
        desenText(str) {
            let res = str;
            const len = str.length;
            let pre4 = '';
            let last6 = '';
            pre4 = str.slice(0, 4);
            last6 = str.slice(Math.max(len - 6, 4));
            const star = Math.max(0, len - 10);
            res = pre4 + '*'.repeat(star) + last6;
            return res;
        },
        //输入框动态脱敏
        desenInputText(e) {
            const ind = e.target.selectionStart - 1;
            let value = this.value;
            const showValue = this.showValue;
            const isAdd = showValue.length > value.length;
            const num = Math.abs(value.length - showValue.length);
            if (isAdd) {
                value =
                    value.slice(0, ind-num+1) +
                    showValue.slice(ind-num+1,ind+1) +
                    value.slice(ind-num+1);
            } else {
                value = value.slice(0, ind + 1) + value.slice(ind + num + 1);
            }
            this.value = value;
            this.showValue = this.desenText(value);
            this.$nextTick(() => {
                const elem = e.target;
                if (elem.setSelectionRange) {
                    // 标准浏览器
                    elem.setSelectionRange(ind + 1, ind + 1);
                } else {
                    // IE9-
                    const range = elem.createTextRange();
                    range.moveStart('character', ind + 1);
                    range.moveEnd('character', ind + 1);
                    range.select();
                }
            });
        },
    }
}
</script>

<style>
.form-item{
    margin-top: 1em;
}
</style>

源码地址

Gitee源码:https://gitee.com/zheng_yongtao/jyeontu-vue-demo

觉得有帮助的同学可以帮忙给我点个star,感激不尽~~~\
有什么想法或者改良可以给我提个pr,十分欢迎~~~\
有什么问题都可以在评论告诉我~~~

说在后面

🎉这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。
目录
相关文章
|
消息中间件 SQL 存储
超详细的RabbitMQ入门,看这篇就够了!
RabbitMQ入门,看这篇就够了
219409 69
|
前端开发
【前端】elementUI表格根据状态显示不同的字体颜色
【前端】elementUI表格根据状态显示不同的字体颜色
699 1
|
小程序 JavaScript
小程序bindtap 和 catchtap 的区别以及如何使用
小程序bindtap 和 catchtap 的区别以及如何使用
599 0
|
监控 前端开发 网络协议
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(5)-Fiddler监控面板详解
【7月更文挑战第20天】Fiddler是一款强大的HTTP协议调试代理工具,它的监控面板是核心功能,记录服务器的请求会话,包括HTTP和HTTPS。监控面板分为多个标签,如统计数据(Statistics)展示性能指标,Inspector用于查看请求和响应的详细内容,AutoResponder允许重定向请求到本地资源,Composer用于构造和调试HTTP请求,还有Orchestra Beta、Fiddler Script、Log和Filters等功能。
574 14
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(5)-Fiddler监控面板详解
|
8月前
|
消息中间件 前端开发 数据可视化
6.4K star!企业级流程引擎黑马,低代码开发竟能如此高效!
"比Activiti更易整合,比传统开发更高效" —— 这款开源流程引擎通过配置化实施、零代码表单开发、多环境支持等特性,正在重新定义企业级应用开发方式!
323 4
|
JavaScript
cnpm 的安装与使用
本文介绍了npm和cnpm的概念、安装nodejs的步骤,以及cnpm的安装和使用方法,提供了通过配置npm使用中国镜像源来加速包下载的替代方案,并说明了如何恢复npm默认仓库地址。
cnpm 的安装与使用
|
JavaScript
js计算时间差,包括计算,天,时,分,秒
js计算时间差,包括计算,天,时,分,秒
1193 16
|
11月前
|
安全 数据库 数据安全/隐私保护
处理用户输入数据格式验证不通过的情况时,如何给出友好的提示信息?
处理用户输入数据格式验证不通过的情况时,如何给出友好的提示信息?
688 78
|
前端开发 JavaScript
原生实现环形进度条
原生实现环形进度条
443 121
|
缓存 JavaScript
vue2知识点:全局事件总线(GlobalEventBus)
vue2知识点:全局事件总线(GlobalEventBus)
339 2
vue2知识点:全局事件总线(GlobalEventBus)