I'm trying to achieve a simple Data Masking Function by replacing some parts of private data to asterisks(*) with javaScript string replace function.
So what I've done is as following:
function privateDataMask(data, options) {
var str = JSON.stringify(data);
var i = 0, len = options.length;
for (i; i < len; i++) {
var opt = options[i];
var key = opt.key;
var reg = opt.reg;
var _reg = new RegExp('"' + key + '":"' + reg.source + '"', 'g'); //To get new reg which includes the key, like /"tel":"(\d{3})(\d*)(\d{4})"/g
str = str.replace(_reg, '"' + key + '":"$1*$3"');
//str = str.replace(_reg, '"' + key + '":"$1' + '*'.repeat($2.length) + '$3",'); //ReferenceError: $2 is not defined
//str = str.replace(_reg, '"' + key + '":"$1' + '*'.repeat(RegExp.$2.length) + '$3",'); //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/n
}
return JSON.parse(str);
}
var data = [{
name: "王梅",
tel: "15812346584",
id: "22040219820418866X"
}, {
name: "吴青峰",
tel: "13921345678",
id: "450328197006157868"
},
{
name: "王张玉成",
tel: "17734685988",
id: "620100198109198020"
}
];
var options = [{
key: 'name',
reg: /([\u4e00-\u9fa5A-Za-z0-9\·\.]?)([\u4e00-\u9fa5A-Za-z0-9\·\.]+)([\u4e00-\u9fa5A-Za-z0-9\·\.]+)/
},
{
key: 'tel',
reg: /(\d{3})(\d*)(\d{4})/
},
{
key: 'id',
reg: /(\d{6})(\d*)(\d{5}(\d|X){1})/
}
]
var maskedData = privateDataMask(data, options);
console.log(maskedData);
It works somehow as expected, but still, I want to make little improvements, which can transfer for example, name: "吴青峰" -> name: "吴*峰", name: "王张玉成" -> name: "王**成", tel: "15812346584" -> tel: "158****6584", etc.
That is, adding multiple asterisks() to the parts replaced, and the number of asterisks() should equal to the length of captured group during String.replace().
As the commented lines indicate, I've tried things like '*'.repeat(RegExp.$2.length), the puzzle is RegExp.$n can only get value after the String.replace() function finishes, which leads to malposition.
Therefore, are there any methods to get the length of captured group concurrently during String.replace() function please ?
You can pass a function as second parameter to .replace() and that function will calculate the amount of *
will be added.
_str = _str.replace(_reg, (text, start, middle, end) => `"${key}":"${start + '*'.repeat(middle.length) + end}"`);
Demo:
function privateDataMask(data, options) {
var str = JSON.stringify(data);
var i = 0;
var len = options.length;
var _str, _data;
for (i; i < len; i++) {
var opt = options[i];
var key = opt.key;
var reg = opt.reg;
var _reg = new RegExp('"' + key + '":"' + reg.source + '"',
'g'); //To get new reg which includes the key, like /"tel":"(\d{3})(\d*)(\d{4})"/g
//console.log(_reg);
if (!_str) {
_str = str;
}
_str = _str.replace(_reg, (text, start, middle, end) => `"${key}":"${start + '*'.repeat(middle.length) + end}"`);
}
_data = JSON.parse(_str);
return _data;
}
var data = [{
name: "王梅",
tel: "15812346584",
id: "22040219820418866X"
}, {
name: "吴青峰",
tel: "13921345678",
id: "450328197006157868"
},
{
name: "王张玉成",
tel: "17734685988",
id: "620100198109198020"
}
];
var options = [{
key: 'name',
reg: /([\u4e00-\u9fa5A-Za-z0-9\·\.]?)([\u4e00-\u9fa5A-Za-z0-9\·\.]+)([\u4e00-\u9fa5A-Za-z0-9\·\.]+)/
},
{
key: 'tel',
reg: /(\d{3})(\d*)(\d{4})/
},
{
key: 'id',
reg: /(\d{6})(\d*)(\d{5}(\d|X){1})/
}
]
var maskedData = privateDataMask(data, options);
console.log(maskedData);