data_masker 1.0.1 copy "data_masker: ^1.0.1" to clipboard
data_masker: ^1.0.1 copied to clipboard

Pure Dart data masking library for sensitive data anonymization. Supports phone, email, ID card, bank card and custom rules.

data_masker #

Pure Dart data masking library for sensitive data anonymization. Works on all Dart platforms with zero dependencies.

Quick Results #

See what data_masker can do at a glance:

Data Type Input Output
Phone 13812345678 138****5678
Email user@example.com use***@example.com
ID Card 110101199001011234 110101********1234
Bank Card 6222021234567890123 6222***********0123
IP Address 192.168.1.100 192.168.***.100
URL https://example.com/api/users https://example.com********
Passport G12345678 G******
License Plate CA12345 CA1***
JWT Token eyJhbGciOiJIUzI1Ni...w5c eyJhbGci****************w5c
UUID 550e8400-e29b-41d4-a716-...0000 550e8400-****-****-****-446655440000
API Key sk_test_abcdefghijklmnop... sk_************
Chinese Name Zhang San, Zhang Sanfeng Zhang ***, Zhang ***
English Name John Doe John D***
Date of Birth 1990-01-01 1990-01-**

Features #

  • Cross-platform: Pure Dart implementation, works everywhere Dart runs
  • 15+ Preset Rules: Phone, email, ID card, bank card, IP, URL, passport, license plate, JWT, UUID, API key, names, date of birth
  • 4 Mask Strategies: Full mask, keep prefix, keep suffix, keep both ends
  • Custom Rules: Field name matching, regex matching, custom logic
  • Nested Support: Recursively masks nested Map and List structures
  • Type Safe: Full null safety support
  • Dart 2.19+: Compatible with a wide range of Dart versions

Getting Started #

Installation #

dependencies:
  data_masker: ^1.0.0
dart pub get

Basic Usage #

import 'package:data_masker/data_masker.dart';

void main() {
  final config = MaskConfig(
    enabled: true,
    rules: [
      PresetMaskRules.phone(),
      PresetMaskRules.email(),
      FieldMaskRule(fieldNames: ['password', 'token']),
    ],
  );

  final masker = DataMasker(config);

  // Mask string
  final maskedString = masker.process('Phone: 13812345678, Email: user@example.com');
  print(maskedString);
  // Output: Phone: 138****5678, Email: use***@example.com

  // Mask Map
  final maskedMap = masker.process({
    'username': 'test',
    'password': 'secret123',
    'phone': '13812345678',
  });
  print(maskedMap);
  // Output: {username: test, password: *********, phone: 138****5678}

  // Mask nested structure
  final nestedData = {
    'user': {
      'name': 'Zhang San',
      'auth': {'token': 'abc123xyz'}
    },
    'contacts': [{'phone': '13987654321'}],
  };
  final maskedNested = masker.process(nestedData);
  print(maskedNested);
  // Output: {user: {name: Zhang ***, auth: {token: *********}}, contacts: [{phone: 139****4321}]}
}

Run Example #

dart run example/data_masker_example.dart

Actual Output:

=== data_masker Complete Example ===

1. MaskStrategy (Masking Strategy)
   full: **********
   keepPrefix: 123*******
   keepSuffix: ******7890
   keepBoth: 123****890

2. PresetMaskRules (Preset Rules)
   Phone: 138****5678
   Email: use***@example.com
   ID Card: 110101********1234
   Bank Card: 6222***********0123
   IP Address: 192.168.***.100
   URL: https://example.com********

3. Supported Data Types
   String: Phone: 138****5678, Email: use***@example.com
   Map: {username: test, password: *********, phone: 138****5678}
   List: [{name: Alice, email: ali***@example.com}, {name: Bob, email: bob***@example.com}]

4. Real-world Scenario
   API Response Masking:
   {code: 200, message: success, data: {user: {id: 123, name: Zhang ***, phone: 138****5678, email: zha***@company.com, idCard: 110101********1234, bankCard: 6222***********0123}, session: {token: ********************, expireTime: 2024-12-31 23:59:59}}}

API Documentation #

MaskStrategy #

Enumeration defining the masking strategy.

Strategy Description Example
full Mask entire value 1234567890**********
keepPrefix Keep prefix, mask rest 1234567890123*******
keepSuffix Keep suffix, mask rest 1234567890******7890
keepBoth Keep both ends, mask middle 1234567890123****890

MaskConfig #

const MaskConfig({
  this.enabled = false,           // Enable/disable masking
  this.defaultStrategy = MaskStrategy.full,
  this.rules = const [],          // List of mask rules
  this.maskChar = '*',            // Mask character: '*' or '#' or any
  this.maxMaskLength = 20,        // Maximum mask characters
  this.caseSensitive = false,     // Case sensitive field matching
});

Example:

final config = MaskConfig(
  enabled: true,
  maskChar: '#',
  maxMaskLength: 10,
  rules: [PresetMaskRules.phone()],
);

final masker = DataMasker(config);
print(masker.process('13812345678'));
// Output: 138####5678

DataMasker #

const DataMasker([this.config = const MaskConfig()]);

Object? process(Object? data);

Supported Types:

Type Behavior
String Apply regex rules to find and mask patterns
Map Recursively process keys and values
Iterable Recursively process each item
Other Convert to string and apply rules

Example:

final masker = DataMasker(MaskConfig(
  enabled: true,
  rules: [PresetMaskRules.email()],
));

// Process String
masker.process('Contact: alice@example.com');
// Output: Contact: ali***@example.com

// Process Map
masker.process({'email': 'bob@example.com'});
// Output: {email: bob***@example.com}

// Process List
masker.process([
  {'name': 'Alice', 'email': 'alice@example.com'},
  {'name': 'Bob', 'email': 'bob@example.com'},
]);
// Output: [{name: Alice, email: ali***@example.com}, {name: Bob, email: bob***@example.com}]

// Process nested structure
masker.process({
  'user': {'name': 'John', 'auth': {'token': 'abc123'}}
});
// Output: {user: {name: John, auth: {token: *********}}}

FieldMaskRule #

Mask values based on field name matching.

const FieldMaskRule({
  required this.fieldNames,       // List of field names to match
  super.strategy = MaskStrategy.full,
  super.keepCount = 4,
  super.customMask,
});

Example:

final rule = FieldMaskRule(
  fieldNames: ['password', 'token', 'secret'],
  strategy: MaskStrategy.keepPrefix,
  keepCount: 2,
);

const config = MaskConfig(enabled: true);

// Check if field matches
rule.matches('password', 'secret123');  // true
rule.matches('username', 'test');       // false

// Apply mask
rule.apply('secret123', config);        // 'se*********'

// Apply to JSON string
rule.applyToJsonString('{"password":"secret123"}', config);
// Output: {"password":"*********"}

RegexMaskRule #

Mask values based on regular expression matching.

const RegexMaskRule({
  required this.pattern,          // RegExp pattern to match
  this.formatter,                 // Custom formatter function
  super.strategy = MaskStrategy.full,
  super.keepCount = 4,
  super.customMask,
});

Example with Strategy:

final rule = RegexMaskRule(
  pattern: RegExp(r'\d{6,8}'),
  strategy: MaskStrategy.keepBoth,
  keepCount: 3,
);

const config = MaskConfig(enabled: true);
rule.apply('ID: 12345678', config);
// Output: ID: 123**678

Example with Custom Formatter:

final rule = RegexMaskRule(
  pattern: RegExp(r'(\d{3})\d{4}(\d{4})'),
  formatter: (match, config) {
    return '${match.group(1)}****${match.group(2)}';
  },
);

rule.apply('13812345678', config);
// Output: 138****5678

CustomMaskRule #

Mask values with custom matching logic.

const CustomMaskRule({
  required this.matcher,          // Custom matcher function
  this.formatter,                 // Custom formatter function
  super.strategy = MaskStrategy.full,
  super.keepCount = 4,
  super.customMask,
});

Example:

// Custom matcher
final rule = CustomMaskRule(
  matcher: (key, value) => key?.toString() == 'custom_field',
  strategy: MaskStrategy.keepPrefix,
  keepCount: 2,
);

rule.matches('custom_field', 'value');  // true
rule.matches('other_field', 'value');   // false
rule.apply('abcdef', config);           // 'ab****'

// Custom formatter
final formatterRule = CustomMaskRule(
  matcher: (key, value) => true,
  formatter: (value) => '[MASKED]',
);

formatterRule.apply('sensitive data', config);
// Output: [MASKED]

MaskUtils #

static String applyMask(
  String value,
  MaskStrategy strategy,
  int? keepCount,
  String? customMask,
  MaskConfig config,
);

Example:

MaskUtils.applyMask('1234567890', MaskStrategy.keepBoth, 3, null, config);
// Output: 123****890

MaskUtils.applyMask('secret', MaskStrategy.full, 4, '[HIDDEN]', config);
// Output: [HIDDEN]

PresetMaskRules #

Individual Rules

// Phone
PresetMaskRules.phone().apply('13812345678', config);
// Output: 138****5678

// Email
PresetMaskRules.email().apply('user@example.com', config);
// Output: use***@example.com

// ID Card
PresetMaskRules.idCard().apply('110101199001011234', config);
// Output: 110101********1234

// Bank Card
PresetMaskRules.bankCard().apply('6222021234567890123', config);
// Output: 6222***********0123

// IP Address
PresetMaskRules.ipAddress().apply('192.168.1.100', config);
// Output: 192.168.***.100

// URL
PresetMaskRules.url().apply('https://example.com/api/users', config);
// Output: https://example.com********

// Passport
PresetMaskRules.passport().apply('G12345678', config);
// Output: G******

// License Plate
PresetMaskRules.plateNumber().apply('CA12345', config);
// Output: CA1***

// JWT Token
PresetMaskRules.jwtToken().apply('eyJhbGciOiJIUzI1Ni...w5c', config);
// Output: eyJhbGci****************w5c

// UUID
PresetMaskRules.uuid().apply('550e8400-e29b-41d4-a716-446655440000', config);
// Output: 550e8400-****-****-****-446655440000

// API Key
PresetMaskRules.apiKey().apply('sk_test_abcdefghijklmnop', config);
// Output: sk_************

// Chinese Name (matches 2-4 Chinese characters)
// Pattern: [\u4e00-\u9fa5]{2,4}
// Keep first char, mask the rest

// English Name
PresetMaskRules.englishName().apply('John Doe', config);
// Output: John D***

// Date of Birth
PresetMaskRules.dateOfBirth().apply('1990-01-01', config);
// Output: 1990-01-**

Preset Combinations

Pre-configured rule combinations for common use cases:

// Financial data: bankCard + idCard + phone + commonFields
final financialConfig = MaskConfig(
  enabled: true,
  rules: PresetMaskRules.financial(),
);

// API logging: jwtToken + apiKey + email + ipAddress + url + commonFields
final apiLogConfig = MaskConfig(
  enabled: true,
  rules: PresetMaskRules.apiLog(),
);

// Personal info: phone + email + idCard + names + dateOfBirth + passport + commonFields
final personalConfig = MaskConfig(
  enabled: true,
  rules: PresetMaskRules.personalInfo(),
);

// Network logging: ipAddress + url + jwtToken + apiKey + email
final networkConfig = MaskConfig(
  enabled: true,
  rules: PresetMaskRules.networkLog(),
);

Advanced Usage #

Disable Masking #

final config = MaskConfig(
  enabled: false,  // All masking disabled
  rules: [PresetMaskRules.phone()],
);

final masker = DataMasker(config);
masker.process('13812345678');
// Output: 13812345678 (unchanged)

Custom Mask Character #

final config = MaskConfig(
  enabled: true,
  maskChar: '#',
  rules: [PresetMaskRules.phone()],
);

final masker = DataMasker(config);
masker.process('13812345678');
// Output: 138####5678

Multiple Rules #

final config = MaskConfig(
  enabled: true,
  rules: [
    PresetMaskRules.phone(),
    PresetMaskRules.email(),
    FieldMaskRule(fieldNames: ['password', 'token']),
    RegexMaskRule(pattern: RegExp(r'\d{8,}')),
  ],
);

final masker = DataMasker(config);
masker.process({
  'phone': '13812345678',
  'email': 'user@example.com',
  'password': 'secret123',
});
// Output: {phone: 138****5678, email: use***@example.com, password: *********}

Platform Support #

  • ✅ Flutter Android
  • ✅ Flutter iOS
  • ✅ Flutter Web
  • ✅ Flutter Desktop (macOS, Linux, Windows)
  • ✅ Dart CLI
  • ✅ Dart Server

Dart Version #

  • Minimum: Dart 2.19.0
  • Recommended: Dart 3.0+

License #

MIT

0
likes
160
points
0
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Pure Dart data masking library for sensitive data anonymization. Supports phone, email, ID card, bank card and custom rules.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

More

Packages that depend on data_masker