本文目录导读:

JavaScript 实现(Web场景)
基础掩码函数
function maskData(data, options = {}) {
const {
maskChar = '*',
visibleStart = 2,
visibleEnd = 2,
pattern = null
} = options;
if (pattern) {
return customPatternMask(data, pattern, maskChar);
}
// 默认掩码:保留首尾指定位数
if (data.length <= visibleStart + visibleEnd) return data;
const start = data.slice(0, visibleStart);
const middle = maskChar.repeat(data.length - visibleStart - visibleEnd);
const end = data.slice(-visibleEnd);
return start + middle + end;
}
// 自定义模式掩码(支持正则)
function customPatternMask(data, pattern, maskChar = '*') {
let result = '';
let patternIndex = 0;
for (let char of data) {
if (pattern[patternIndex] === 'X' && char.match(/\d/)) {
result += char; // X 表示保留数字
} else if (pattern[patternIndex] === 'A' && char.match(/[a-zA-Z]/)) {
result += char; // A 表示保留字母
} else if (pattern[patternIndex] === '*') {
result += maskChar; // * 表示掩码
} else {
result += char; // 其他字符原样显示
}
patternIndex++;
}
return result;
}
// 使用示例
console.log(maskData("1234567890")); // 12******90
console.log(maskData("test@email.com", {
pattern: "****@***.***"
})); // ****@ema**.com
Python 实现
灵活掩码类
class DataMask:
def __init__(self, mask_char='*'):
self.mask_char = mask_char
def mask(self, data, format_type='default', **kwargs):
if format_type == 'phone':
return self._mask_phone(data)
elif format_type == 'email':
return self._mask_email(data)
elif format_type == 'custom':
return self._custom_mask(data, kwargs.get('pattern'))
elif format_type == 'regex':
return self._regex_mask(data, kwargs.get('pattern'))
else:
return self._default_mask(data, **kwargs)
def _default_mask(self, data, visible_start=2, visible_end=2):
if len(data) <= visible_start + visible_end:
return data
return data[:visible_start] + self.mask_char * (len(data) - visible_start - visible_end) + data[-visible_end:]
def _mask_phone(self, phone):
return phone[:3] + '****' + phone[-4:] if len(phone) >= 7 else phone
def _mask_email(self, email):
local, domain = email.split('@')
return local[:3] + '***@' + domain
def _custom_mask(self, data, pattern):
"""自定义模式掩码,支持:X-保留数字, A-保留字母, *-掩码"""
result = []
for char, p in zip(data, pattern):
if p == 'X' and char.isdigit():
result.append(char)
elif p == 'A' and char.isalpha():
result.append(char)
elif p == '*':
result.append(self.mask_char)
else:
result.append(char)
return ''.join(result)
def _regex_mask(self, data, pattern):
import re
return re.sub(pattern, self.mask_char, data)
# 使用示例
masker = DataMask()
print(masker.mask("1234567890")) # 12******90
print(masker.mask("13800138000", format_type='phone')) # 138****8000
print(masker.mask("user@example.com", format_type='custom',
pattern="XXX****@********")) # use****@examp***.com
通用配置式掩码
JSON配置文件
{
"masks": {
"phone": {
"pattern": "前置显示3位-中间掩码4位-后置显示4位",
"visible_start": 3,
"visible_end": 4,
"mask_char": "*"
},
"id_card": {
"pattern": "前6位显示-后4位显示,中间掩码",
"visible_start": 6,
"visible_end": 4,
"mask_char": "X"
},
"email_local": {
"pattern": "保留前3位和后2位,中间掩码",
"pre_visible": 3,
"suf_visible": 2,
"mask_char": "*"
},
"custom_regex": {
"format": "regex",
"pattern": "(?<=.{3}).(?=.{4})",
"mask_char": "#"
}
}
}
动态加载掩码规则
class MaskManager {
constructor(rules = {}) {
this.rules = rules;
}
applyMask(data, ruleName, customOptions = {}) {
const rule = this.rules[ruleName] || {};
const options = { ...rule, ...customOptions };
switch (options.format) {
case 'regex':
return data.replace(new RegExp(options.pattern, 'g'), options.mask_char || '*');
case 'positions':
return this._positionalMask(data, options);
default:
return this._defaultMask(data, options);
}
}
_positionalMask(data, options) {
const {
positions = [], // 需要掩码的位置索引数组
maskChar = '*',
preserveLength = true
} = options;
let result = data.split('');
for (let pos of positions) {
if (result[pos] !== undefined) {
result[pos] = preserveLength ? maskChar : '';
}
}
return result.join('');
}
_defaultMask(data, { visibleStart = 2, visibleEnd = 2, maskChar = '*' }) {
if (data.length <= visibleStart + visibleEnd) return data;
return data.slice(0, visibleStart) +
maskChar.repeat(data.length - visibleStart - visibleEnd) +
data.slice(-visibleEnd);
}
}
// 使用示例
const maskManager = new MaskManager({
'bank_account': {
format: 'positions',
positions: [0, 1, 2, -4, -3, -2, -1], // 前3位和最后4位掩码
maskChar: '#'
}
});
console.log(maskManager.applyMask("6222021234567890", "bank_account"));
// ###2021234#######
高级特性 - 条件掩码
def conditional_mask(data, rules):
"""
条件掩码:根据数据内容动态生成掩码规则
rules: [((条件函数), 掩码参数), ...]
"""
for condition, mask_params in rules:
if condition(data):
return apply_mask(data, mask_params)
return data # 没有匹配规则则返回原始数据
def apply_mask(data, params):
mask_char = params.get('mask_char', '*')
visible_start = params.get('visible_start', 0)
visible_end = params.get('visible_end', 0)
if len(data) <= visible_start + visible_end:
return data
return data[:visible_start] + mask_char * (len(data) - visible_start - visible_end) + data[-visible_end:]
# 使用示例
rules = [
(lambda x: len(x) == 11 and x.isdigit(), {'visible_start': 3, 'visible_end': 4}), # 手机号
(lambda x: '@' in x, {'visible_start': 2, 'visible_end': 0}), # 邮箱
(lambda x: len(x) == 18 and x[:-1].isdigit(), {'visible_start': 6, 'visible_end': 4}), # 身份证号
]
print(conditional_mask("13800138000", rules)) # 138****8000
print(conditional_mask("test@example.com", rules)) # te***@example.com
最佳实践建议
- 统一管理:使用配置文件或数据库统一管理掩码规则
- 性能优化:对于大量数据,预编译正则表达式
- 安全考虑:不要在客户端进行敏感数据的掩码操作
- 可追溯性:记录掩码操作的日志,便于审计
- 国际化:考虑不同国家的数据格式(如电话号码长度不同)
这些方法可以根据具体需求组合使用,实现灵活的自定义数据掩码功能。