脚本如何自定义数据掩码格式

wen 实用脚本 30

本文目录导读:

脚本如何自定义数据掩码格式

  1. JavaScript 实现(Web场景)
  2. Python 实现
  3. 通用配置式掩码
  4. 高级特性 - 条件掩码
  5. 最佳实践建议

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

最佳实践建议

  1. 统一管理:使用配置文件或数据库统一管理掩码规则
  2. 性能优化:对于大量数据,预编译正则表达式
  3. 安全考虑:不要在客户端进行敏感数据的掩码操作
  4. 可追溯性:记录掩码操作的日志,便于审计
  5. 国际化:考虑不同国家的数据格式(如电话号码长度不同)

这些方法可以根据具体需求组合使用,实现灵活的自定义数据掩码功能。

抱歉,评论功能暂时关闭!