tuomin 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,73 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags:
7
+ - "v*"
8
+ pull_request:
9
+ branches: [main]
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+
23
+ - name: Set up Python ${{ matrix.python-version }}
24
+ run: uv python install ${{ matrix.python-version }}
25
+
26
+ - name: Install dependencies
27
+ run: uv sync --python ${{ matrix.python-version }}
28
+
29
+ - name: Run tests
30
+ run: uv run pytest tests/ -v
31
+
32
+ build:
33
+ needs: test
34
+ runs-on: ubuntu-latest
35
+ if: startsWith(github.ref, 'refs/tags/v')
36
+ permissions:
37
+ id-token: write
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+
41
+ - name: Install uv
42
+ uses: astral-sh/setup-uv@v4
43
+
44
+ - name: Set up Python
45
+ run: uv python install 3.12
46
+
47
+ - name: Build package
48
+ run: uv build
49
+
50
+ - name: Upload artifacts
51
+ uses: actions/upload-artifact@v4
52
+ with:
53
+ name: dist
54
+ path: dist/
55
+
56
+ publish:
57
+ needs: build
58
+ runs-on: ubuntu-latest
59
+ if: startsWith(github.ref, 'refs/tags/v')
60
+ permissions:
61
+ id-token: write
62
+ environment:
63
+ name: pypi
64
+ url: https://pypi.org/project/tuomin/
65
+ steps:
66
+ - name: Download artifacts
67
+ uses: actions/download-artifact@v4
68
+ with:
69
+ name: dist
70
+ path: dist/
71
+
72
+ - name: Publish to PyPI
73
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,22 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ *.egg
8
+
9
+ # Virtual environments
10
+ .venv/
11
+
12
+ # IDE
13
+ .vscode/
14
+ .idea/
15
+
16
+ # OS
17
+ .DS_Store
18
+
19
+ # Test
20
+ *.xlsx
21
+ *.xls
22
+ !tests/fixtures/
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,89 @@
1
+ # Tuomin - Excel 脱敏工具
2
+
3
+ ## 术语表
4
+
5
+ ### 脱敏 (Masking)
6
+ 对 Excel 文件中个人敏感信息进行变换处理,使其不再能识别原始主体。
7
+
8
+ ### 替换 (Replace)
9
+ 用 `*` 替换敏感字段中的特定字符,保留部分原文特征。
10
+
11
+ 各字段类型的替换规则:
12
+ | 字段类型 | 保留规则 | 示例 |
13
+ |---|---|---|
14
+ | 姓名 | 保留姓,名用 `*` 替换 | 张三丰 → 张\*\* |
15
+ | 手机号 | 保留前 3 后 4,中间用 `*` | 13812341234 → 138\*\*\*\*1234 |
16
+ | 身份证号 | 保留前 3 后 4,中间用 `*` | 310101199001011234 → 310\*\*\*\*\*\*\*\*\*\*\*\*1234 |
17
+ | 邮箱 | 用户名首字符 + `*` + @域名保留 | zhangsan@qq.com → z\*\*\*\*\*\*\*\*@qq.com |
18
+ | 银行卡号 | 保留前 4 后 4,中间用 `*` | 6222021234565678 → 6222\*\*\*\*\*5678 |
19
+ | 地址 | 保留省市,后面用 `*` | 上海市浦东新区张江路88号 → 上海市\*\*\*\*\*\*\*\*\*\* |
20
+
21
+ ### 重构 (Reconstruct)
22
+ 重新生成与现实世界毫无关联的假数据。生成结果必须不可能对应任何真实个人信息。
23
+
24
+ 各字段类型的重构规则:
25
+ | 字段类型 | 重构规则 | 示例 |
26
+ |---|---|---|
27
+ | 姓名 | 常见姓 + 中文数字(一二三四五六七八九) | 张三四、李一二 |
28
+ | 手机号 | 110 开头 + 8 位随机数字 | 11056781234 |
29
+ | 身份证号 | 999 开头(不存在的地区码)+ 随机数字 + 随机校验位 | 999999199901019923 |
30
+ | 邮箱 | 随机字符 + @notexist.invalid | a3k9x@notexist.invalid |
31
+ | 银行卡号 | 0000 开头(不存在的 BIN)+ 随机数字 | 0000123456781234 |
32
+ | 地址 | 省 + 市 + 虚构路名 + 数字号 | 广东省深圳市虚构路999号 |
33
+
34
+ #### 叠加重构 (Overlay Reconstruct)
35
+ 原文可能已经被替换过(包含 `*`),如 `138****1234` 或 `张**`。重构时需识别此类已脱敏数据,忽略 `*` 占位符,直接生成新的假数据。即:无论原文是明文还是已替换,重构结果一致。
36
+
37
+ ### 一致性 (Consistency)
38
+ 同一原文值在同一列中出现多次时,脱敏结果必须一致。无论替换还是重构,相同的输入始终映射到相同的输出。实现上需维护运行时映射表(原文 → 脱敏结果)。
39
+
40
+ ### 空值与非标准值处理
41
+ 空单元格或不符合该字段类型格式的值(如手机号列里写了"未知"),原样保留不做脱敏,不报错。
42
+
43
+ ### 编码处理
44
+ - xlsx 内部为 UTF-8,openpyxl 自动处理
45
+ - xls 可能为 GBK/GB2312 等编码,读取时需显式处理编码检测与转换
46
+ - 控制台输出需适配操作系统默认编码(Windows GBK / macOS Linux UTF-8),避免 print 乱码
47
+ - 含中文的文件路径需确保路径编码与操作系统一致
48
+
49
+ ### 敏感字段类型 (Sensitive Field Type)
50
+ 可识别的个人信息类别,包括:姓名、手机号、身份证号、邮箱、银行卡号、地址等。
51
+
52
+ ### 列映射 (Column Mapping)
53
+ 用户为指定列选择对应敏感字段类型的配置关系。例如:第 3 列 → 手机号。
54
+
55
+ ## 界面
56
+
57
+ ### 技术规格
58
+ - Python >= 3.8
59
+ - 单文件工具:`tuomin.py`
60
+ - 使用 `argparse` 解析命令行参数,自动支持 `--help`
61
+
62
+ ### 依赖
63
+ - `openpyxl`:读写 xlsx
64
+ - `xlrd`:读取 xls
65
+ - 标准库:`argparse`、`string`、`random`、`re`、`os`
66
+ - 不使用 pandas
67
+
68
+ ### 交互方式
69
+ 纯命令行参数,无交互式提示、无 Web UI。
70
+
71
+ ### 命令行格式(示意)
72
+ ```
73
+ python tuomin.py <input_file> --sheet <sheet> --col <col>:<type>:<method> [--col ...] --output <output_file>
74
+ ```
75
+ - `--sheet`:可选,指定 sheet 名称或索引。默认第一个 sheet
76
+ - `--col`:可多次指定,格式为 `列字母:字段类型:脱敏方式`,如 `C:phone:reconstruct`。列用 Excel 风格字母标识(A, B, C, ...)
77
+
78
+ 字段类型标识:
79
+ | 字段类型 | 命令行标识 |
80
+ |---|---|
81
+ | 姓名 | `name` |
82
+ | 手机号 | `phone` |
83
+ | 身份证号 | `idcard` |
84
+ | 邮箱 | `email` |
85
+ | 银行卡号 | `bankcard` |
86
+ | 地址 | `address` |
87
+
88
+ 脱敏方式标识:`replace` / `reconstruct`
89
+ - `--output`:可选,输出文件路径。始终生成新文件,永不覆盖原文件。若未指定,在同目录生成 `_masked.xlsx` 后缀文件(如 `data.xlsx` → `data_masked.xlsx`)。输出格式统一为 xlsx,无论输入是 xls 还是 xlsx。
tuomin-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,107 @@
1
+ Metadata-Version: 2.4
2
+ Name: tuomin
3
+ Version: 0.1.0
4
+ Summary: Excel 脱敏工具 - 对 xls/xlsx 文件中的个人敏感信息进行替换或重构脱敏
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.8
7
+ Requires-Dist: openpyxl>=3.0.0
8
+ Requires-Dist: xlrd>=2.0.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # Tuomin - Excel 脱敏工具
12
+
13
+ 命令行工具,对 xls/xlsx 文件中的个人敏感信息进行脱敏处理。
14
+
15
+ ## 安装
16
+
17
+ ```bash
18
+ pip install openpyxl xlrd
19
+ ```
20
+
21
+ Python >= 3.8
22
+
23
+ ## 用法
24
+
25
+ ```bash
26
+ python tuomin.py <input_file> --col <列字母>:<字段类型>:<脱敏方式> [--col ...] [选项]
27
+ ```
28
+
29
+ ### 参数
30
+
31
+ | 参数 | 说明 |
32
+ |---|---|
33
+ | `input_file` | 输入的 xls/xlsx 文件路径 |
34
+ | `--sheet` | Sheet 名称或索引(从 0 开始),默认第一个 Sheet |
35
+ | `--col` | 指定脱敏列,格式 `列字母:字段类型:脱敏方式`,可多次使用 |
36
+ | `--output` | 输出文件路径,默认在同目录生成 `_masked.xlsx` 后缀文件 |
37
+
38
+ ### 字段类型
39
+
40
+ | 标识 | 说明 |
41
+ |---|---|
42
+ | `name` | 姓名 |
43
+ | `phone` | 手机号 |
44
+ | `idcard` | 身份证号 |
45
+ | `email` | 邮箱 |
46
+ | `bankcard` | 银行卡号 |
47
+ | `address` | 地址 |
48
+
49
+ ### 脱敏方式
50
+
51
+ | 标识 | 说明 |
52
+ |---|---|
53
+ | `replace` | 用 `*` 替换敏感部分,保留部分原文特征 |
54
+ | `reconstruct` | 生成与现实无关的假数据 |
55
+
56
+ ## 示例
57
+
58
+ 替换单列手机号:
59
+
60
+ ```bash
61
+ python tuomin.py data.xlsx --col C:phone:replace
62
+ ```
63
+
64
+ 重构多列:
65
+
66
+ ```bash
67
+ python tuomin.py data.xls --col B:name:reconstruct --col D:idcard:reconstruct --output result.xlsx
68
+ ```
69
+
70
+ 指定 Sheet + 混合脱敏:
71
+
72
+ ```bash
73
+ python tuomin.py data.xlsx --sheet 员工信息 --col B:name:replace --col C:phone:reconstruct --col E:email:replace
74
+ ```
75
+
76
+ ## 替换规则
77
+
78
+ | 字段类型 | 保留规则 | 示例 |
79
+ |---|---|---|
80
+ | 姓名 | 保留姓,名用 `*` | 张三丰 → `张**` |
81
+ | 手机号 | 保留前 3 后 4 | 13812341234 → `138****1234` |
82
+ | 身份证号 | 保留前 3 后 4 | 310101199001011234 → `310***********1234` |
83
+ | 邮箱 | 首字符 + `*` + 域名 | zhangsan@qq.com → `z*******@qq.com` |
84
+ | 银行卡号 | 保留前 4 后 4 | 6222021234565678 → `6222********5678` |
85
+ | 地址 | 保留到区/县 | 上海市浦东新区张江路88号 → `上海市浦东新区******` |
86
+
87
+ ## 重构规则
88
+
89
+ 生成的假数据不可能对应任何真实信息:
90
+
91
+ | 字段类型 | 生成规则 | 示例 |
92
+ |---|---|---|
93
+ | 姓名 | 姓氏 + 中文数字 | 张三四 |
94
+ | 手机号 | 110 开头(报警号段) | 11056781234 |
95
+ | 身份证号 | 999 开头(不存在的地区码) | 999999199901019923 |
96
+ | 邮箱 | @notexist.invalid | a3k9x@notexist.invalid |
97
+ | 银行卡号 | 0000 开头(不存在的 BIN) | 0000123456781234 |
98
+ | 地址 | 虚构路 + 数字号 | 广东省深圳市虚构路999号 |
99
+
100
+ ## 特性
101
+
102
+ - **一致性** — 同一原文在同一列中始终映射到相同结果
103
+ - **叠加重构** — 对已包含 `*` 的替换数据可再次重构
104
+ - **空值/非标准值** — 原样保留,不报错
105
+ - **编码兼容** — 自动处理 xls GBK 编码和控制台输出编码
106
+ - **安全** — 永不覆盖原文件,始终生成新文件
107
+ - **格式统一** — 输出始终为 xlsx
tuomin-0.1.0/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Tuomin - Excel 脱敏工具
2
+
3
+ 命令行工具,对 xls/xlsx 文件中的个人敏感信息进行脱敏处理。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install openpyxl xlrd
9
+ ```
10
+
11
+ Python >= 3.8
12
+
13
+ ## 用法
14
+
15
+ ```bash
16
+ python tuomin.py <input_file> --col <列字母>:<字段类型>:<脱敏方式> [--col ...] [选项]
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ | 参数 | 说明 |
22
+ |---|---|
23
+ | `input_file` | 输入的 xls/xlsx 文件路径 |
24
+ | `--sheet` | Sheet 名称或索引(从 0 开始),默认第一个 Sheet |
25
+ | `--col` | 指定脱敏列,格式 `列字母:字段类型:脱敏方式`,可多次使用 |
26
+ | `--output` | 输出文件路径,默认在同目录生成 `_masked.xlsx` 后缀文件 |
27
+
28
+ ### 字段类型
29
+
30
+ | 标识 | 说明 |
31
+ |---|---|
32
+ | `name` | 姓名 |
33
+ | `phone` | 手机号 |
34
+ | `idcard` | 身份证号 |
35
+ | `email` | 邮箱 |
36
+ | `bankcard` | 银行卡号 |
37
+ | `address` | 地址 |
38
+
39
+ ### 脱敏方式
40
+
41
+ | 标识 | 说明 |
42
+ |---|---|
43
+ | `replace` | 用 `*` 替换敏感部分,保留部分原文特征 |
44
+ | `reconstruct` | 生成与现实无关的假数据 |
45
+
46
+ ## 示例
47
+
48
+ 替换单列手机号:
49
+
50
+ ```bash
51
+ python tuomin.py data.xlsx --col C:phone:replace
52
+ ```
53
+
54
+ 重构多列:
55
+
56
+ ```bash
57
+ python tuomin.py data.xls --col B:name:reconstruct --col D:idcard:reconstruct --output result.xlsx
58
+ ```
59
+
60
+ 指定 Sheet + 混合脱敏:
61
+
62
+ ```bash
63
+ python tuomin.py data.xlsx --sheet 员工信息 --col B:name:replace --col C:phone:reconstruct --col E:email:replace
64
+ ```
65
+
66
+ ## 替换规则
67
+
68
+ | 字段类型 | 保留规则 | 示例 |
69
+ |---|---|---|
70
+ | 姓名 | 保留姓,名用 `*` | 张三丰 → `张**` |
71
+ | 手机号 | 保留前 3 后 4 | 13812341234 → `138****1234` |
72
+ | 身份证号 | 保留前 3 后 4 | 310101199001011234 → `310***********1234` |
73
+ | 邮箱 | 首字符 + `*` + 域名 | zhangsan@qq.com → `z*******@qq.com` |
74
+ | 银行卡号 | 保留前 4 后 4 | 6222021234565678 → `6222********5678` |
75
+ | 地址 | 保留到区/县 | 上海市浦东新区张江路88号 → `上海市浦东新区******` |
76
+
77
+ ## 重构规则
78
+
79
+ 生成的假数据不可能对应任何真实信息:
80
+
81
+ | 字段类型 | 生成规则 | 示例 |
82
+ |---|---|---|
83
+ | 姓名 | 姓氏 + 中文数字 | 张三四 |
84
+ | 手机号 | 110 开头(报警号段) | 11056781234 |
85
+ | 身份证号 | 999 开头(不存在的地区码) | 999999199901019923 |
86
+ | 邮箱 | @notexist.invalid | a3k9x@notexist.invalid |
87
+ | 银行卡号 | 0000 开头(不存在的 BIN) | 0000123456781234 |
88
+ | 地址 | 虚构路 + 数字号 | 广东省深圳市虚构路999号 |
89
+
90
+ ## 特性
91
+
92
+ - **一致性** — 同一原文在同一列中始终映射到相同结果
93
+ - **叠加重构** — 对已包含 `*` 的替换数据可再次重构
94
+ - **空值/非标准值** — 原样保留,不报错
95
+ - **编码兼容** — 自动处理 xls GBK 编码和控制台输出编码
96
+ - **安全** — 永不覆盖原文件,始终生成新文件
97
+ - **格式统一** — 输出始终为 xlsx
@@ -0,0 +1,26 @@
1
+ [project]
2
+ name = "tuomin"
3
+ version = "0.1.0"
4
+ description = "Excel 脱敏工具 - 对 xls/xlsx 文件中的个人敏感信息进行替换或重构脱敏"
5
+ readme = "README.md"
6
+ requires-python = ">=3.8"
7
+ license = "MIT"
8
+ dependencies = [
9
+ "openpyxl>=3.0.0",
10
+ "xlrd>=2.0.0",
11
+ ]
12
+
13
+ [project.scripts]
14
+ tuomin = "tuomin:main"
15
+
16
+ [build-system]
17
+ requires = ["hatchling"]
18
+ build-backend = "hatchling.build"
19
+
20
+ [tool.hatch.build.targets.wheel]
21
+ packages = ["src/tuomin"]
22
+
23
+ [dependency-groups]
24
+ dev = [
25
+ "pytest>=7.0.0",
26
+ ]