第 15 章:编码、加密、随机数与解析工具
所有便利函数都有边界:编码不等于加密,伪随机不等于安全随机,低层解析不等于完整协议解析器。
1. Base64 的契约
EncodingUtil::base64_encode() 接受任意二进制字节。base64_decode() 只接受长度、字符和补位合法的无换行 Base64;非法输入返回空字符串。空输入同样返回空字符串,因此“空输入”和“非法输入”的区分需要由调用上下文保留。
Base64 不是加密。任何人都能还原数据,不能用于隐藏密码、Token 或密钥。
2. SHA-1 与 AES-256-CBC
| API | 输出/行为 | 边界 |
|---|---|---|
sha1() | 20 字节原始摘要 | 协议兼容用途;不用于密码或新签名设计 |
sha11() | 40 字符十六进制摘要 | 可读格式不增加安全性 |
encryptSymmetric(...,outputLength) | AES-256-CBC,并返回实际密文长度 | 输出缓冲区至少为明文长度 + EVP_MAX_BLOCK_LENGTH |
decryptSymmetric(...,outputLength) | 验证填充并返回实际明文长度 | 结果是二进制字节,不自动补 \0 |
无 outputLength 的重载仅用于兼容;带长度的重载能明确返回实际输出字节数。CBC 不提供完整性认证,传输场景通常由 TLS 负责;独立存储密文还涉及完整性认证,通常由 MAC 或 AEAD 方案提供。
3. 随机字符串
RandomUtil::getRandomStr_base64(str,n) 返回长度严格为 n 的 Base64 字符集伪随机文本。它不带 = 补位,也不保证能作为 Base64 解码,因为它不是“随机字节再编码”。它适合展示 ID、测试数据和采样,不适合作为安全 Token、密钥或 IV。
4. 数字、精度和字节序
NumberStringConvertUtil要求整个输入都合法;8080abc会失败并写入回退值。toBool()只有true/True/TRUE返回 true,其余内容返回 false;它没有独立失败状态。PrecisionUtil有格式化字符串和原地修改数值两类接口。金额与精确账务更适合十进制定点或专用高精度类型。NetworkOrderUtil::htonl_ntohl_64()按当前 Linux 64 位unsigned long交换 8 字节;新协议更适合明确使用uint64_t。
5. HTTP、Query 与位工具
| 工具 | 已经保证 | 没有保证 |
|---|---|---|
HttpStringUtil::get_value_header | Header 名不区分大小写,并跳过冒号后的空格/Tab | 不是完整 HTTP parser |
get_value_str | 按 & 字段边界匹配键,id 不会误匹配 userid | 不执行 URL decode,也不区分“无值”和“未找到”的空结果 |
WebsocketStringUtil | 计算 RFC 6455 Accept 值 | 该函数主要服务于 WebSocket 协议实现,业务层通常无需直接调用 |
BitUtil | 拒绝超长、非 01 位串和非法位位置 | 失败时多使用 0/空结果,没有统一错误对象 |
注意 string_view 生命周期。
HttpStringUtil 的 string_view 重载返回的是原输入字符串中的非拥有视图;原字符串被销毁、重新分配或修改后,视图不能继续使用。需要长期保存时应立即复制为 std::string。服务端回调通常直接使用框架已经解析好的 HttpRequestInformation;这些低层工具主要用于受控字符串和协议实现。