安全掩码需先校验长度再操作下标,推荐用replace()替代直接赋值防越界;批量掩码用substr拼接更直观;中文需UTF-8解码后按码点处理,结构化字段优先按ASCII规则脱敏。

如何用 std::string 做固定位置掩码而不越界
直接操作字符串下标最常见也最容易崩——比如对空串或长度不足的串调用 str[3] = '*',结果是未定义行为。C++ 不做运行时边界检查,出问题往往表现为偶发崩溃或脏数据。
安全做法是先校验长度再修改:
- 用
str.length() >= target_pos + 1判断是否可写(注意:下标从 0 开始) - 掩码字符建议统一用
'*'或'#',避免混用导致规则不一致 - 若需批量掩码多个位置(如第 4–7 位),优先用
substr()拆分 + 拼接,比循环赋值更直观
手机号、身份证号等典型格式的掩码逻辑怎么写
不同字段脱敏规则差异大,硬编码位置容易维护错。推荐把规则抽成结构体,按类型查表:
struct MaskRule {
size_t start; // 起始下标(含)
size_t end; // 结束下标(含)
char mask_char;
};
const std::map<:string maskrule> rules = {
{"phone", {3, 6, '*'}}, // 138****1234
{"idcard", {6, 13, '*'}} // 110101****000000X
};
</:string>
注意:身份证末位可能是 'X',掩码时要保留最后一位,即 end = len - 2 而非固定值;手机号国内多为 11 位,但带区号或国际格式需提前清洗。
std::string::replace() 和直接赋值哪个更合适
两者都能用,但语义和性能有区别:
-
str[pos] = '*'最快,适合单点修改,但必须确保pos -
str.replace(pos, 1, 1, '*')更安全(内部会检查长度),适合嵌入式或高可靠性场景 - 连续掩码区间(如 4 个字符)用
replace(start, len, len, '*')比循环调用operator[]少一次内存重分配 - 别用
replace()处理超长字符串高频调用——它可能触发小字符串优化(SSO)失效,导致堆分配
中文字符掩码要特别注意什么
UTF-8 编码下,一个中文字符占 3 字节,但逻辑上是 1 个字符。直接按字节下标掩码会导致乱码,比如把“张三丰”中间字节改成 '*',可能变成“张丰”。
解决方法只有两个:
- 业务层约定输入为纯 ASCII(如手机号、邮箱),避开多字节问题
- 真要处理中文,必须先用 UTF-8 解码库(如
utf8cpp)转成std::u32string,按 Unicode 码点索引,掩码后再转回 UTF-8 - 切勿用
std::wstring想当然——Windows 下是 UTF-16,Linux 下常是 UCS-4,跨平台直接废掉
实际项目里,90% 的脱敏需求发生在结构化字段(手机号、银行卡号、邮箱本地部分),这些全是 ASCII,中文名通常整体加密或不脱敏——这点很容易被忽略,一上来就啃 UTF-8 反而绕远路。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











