如何优雅的对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,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。
目录
相关文章
|
3月前
表单项validator的校验tip未撑起高度,导致遮盖下边项的内容
表单项validator的校验tip未撑起高度,导致遮盖下边项的内容
14 0
表单项validator的校验tip未撑起高度,导致遮盖下边项的内容
自定义实体拖动过程中不实时显示
自定义实体拖动过程中不实时显示
|
1月前
|
供应链 搜索推荐
偏好类标签支持自定义统计方式,标签场景覆盖更广
在个性化营销场景,零售商必须理解顾客的行为才能更准确的预测客户需求,优化库存管理、制定营销策略,并提供个性化的购物体验,然而偏好类标签的加工不仅仅是简单的属性出现频次或最大值的统计,Dataphin V4.0版本新增了自定义统计的方式加工偏好标签,通过简单的配置即可完成复杂的标签加工场景。
|
9月前
layui表单select框同时支持下拉和输入的解决方案
layui表单select框同时支持下拉和输入的解决方案
164 0
|
5月前
layui input框日期框列表显示默认历史搜索记录
layui input框日期框列表显示默认历史搜索记录
|
6月前
|
存储
65EasyUI 表单 - 过滤下拉数据网格
65EasyUI 表单 - 过滤下拉数据网格
27 0
“关联表单”组件文本数据筛选只支持包含条件的解决方案
在“关联表单”中使用数据筛选功能筛选文本时条件只有”包含“,此文章通过增加一个”下拉单选“组件,变相解决这个问题。
151 0
|
前端开发
前端:input 标签取消账号填充
前端:input 标签取消账号填充
|
移动开发 JavaScript 前端开发
表单文本框的使用(二) 输入过滤(合成事件)
表单文本框的使用(二) 输入过滤(合成事件)
257 0