c++oding="utf-8" ?>
合法sha1字符串长度必须为40个十六进制字符,且每个字符限于0-9a-fa-f;先校验长度再逐字符验证,推荐用std::isxdigit(需转unsigned char)确保安全。

SHA1字符串长度必须是40个十六进制字符
合法的SHA1哈希值是20字节二进制数据的十六进制表示,固定为40个0-9a-f(或0-9A-F)字符。长度不等于40直接判否,这是最快、最可靠的前置过滤条件。
实操建议:
- 先用
str.length() == 40快速排除绝大多数非法输入 - 不要依赖
std::hex流解析后再检查——它会静默跳过非十六进制字符,导致误判 - 注意:空字符串、含空格、含下划线、含中文等都应在此步失败
每个字符必须属于十六进制字符集
仅长度正确不够,还要逐字符验证是否在 0123456789abcdefABCDEF 中。C++标准库没有现成的“是否为hex char”函数,需手动检查或用查表法。
实操建议:
- 推荐用
std::all_of(str.begin(), str.end(), [](char c) { return std::isxdigit(static_cast<unsigned char>(c)); })</unsigned> - 注意
std::isxdigit对char的符号敏感,务必转成unsigned char防止负值导致UB - 避免手写
c >= '0' && c ——易漏大小写或打错范围
不建议用正则表达式做主校验
虽然 std::regex 能写成 "^[a-fA-F0-9]{40}$",但实际项目中它开销大、编译慢、跨平台行为不一致(如某些libstdc++版本对 ^/$ 支持不佳),且错误提示不直观。
实操建议:
- 调试阶段可临时用正则辅助验证逻辑,但生产代码中优先用长度+
std::isxdigit - 若已用正则,确保使用
std::regex_constants::icase并启用 ECMAScript 语法 - 注意:MSVC 的
std::regex在较老版本中性能极差,可能卡主线程
区分“格式合法”和“语义合法”
上述检查只保证字符串是「看起来像SHA1」,不保证它真由某个内容计算得出。例如 "0000000000000000000000000000000000000000" 格式完全合法,但现实中几乎不可能是真实SHA1输出(碰撞除外)。
实操建议:
- 业务层若需进一步验证(如确认该SHA1曾出现在数据库中),必须额外查存储,不能仅靠格式判断
- 不要试图通过“是否全零”“是否递增”等启发式规则过滤——SHA1输出应视为均匀随机分布
- 如果上游传入的是带
sha1://前缀或git对象ID(40位但可能是其他哈希),需先剥离前缀再校验
std::isxdigit 的类型转换、正则的引擎差异、以及混淆格式与语义合法性上出问题。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











