使用OpenSSL的EVP接口计算SHA256或MD5摘要最稳妥:先EVP_MD_CTX_new,再EVP_DigestInit_ex选算法,EVP_DigestUpdate分段输入,EVP_DigestFinal_ex获取二进制结果,最后转十六进制;注意错误检查、内存释放及线程安全。

直接用 OpenSSL 的 EVP 接口是最稳妥、跨平台且符合现代实践的方式。别碰老的 MD5() 或 SHA256() 单独函数,它们已弃用且不支持流式计算。
1. 编译前准备:链接 OpenSSL 库
确保系统已安装 OpenSSL 开发包(如 Ubuntu 上 sudo apt install libssl-dev),编译时加链接选项:
g++ your_file.cpp -lssl -lcrypto
Windows 下若用 MinGW 或 MSVC,需对应配置 OpenSSL 的头文件路径和 .lib/.a 文件。
2. 用 EVP 接口计算字符串的 SHA256(推荐写法)
以下代码适用于任意长度输入,支持增量更新(可用于大文件或网络流):
立即学习“C++免费学习笔记(深入)”;
说明:先初始化上下文(EVP_MD_CTX_new),选算法(EVP_sha256()),更新数据(EVP_DigestUpdate),最后获取摘要(EVP_DigestFinal_ex)。
建议步骤:
- 调用
EVP_MD_CTX_new()创建上下文 - 用
EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr)初始化 - 多次调用
EVP_DigestUpdate(ctx, data, len)输入数据(可分段) - 用
EVP_DigestFinal_ex(ctx, md, &md_len)获取 32 字节二进制结果 - 用
printf("%02x", md[i])转成十六进制字符串(共 64 个字符) - 别忘了
EVP_MD_CTX_free(ctx)清理
3. MD5 同理,只换算法名即可
把上面的 EVP_sha256() 换成 EVP_md5(),摘要长度变为 16 字节(32 位 hex 字符串)。注意:MD5 不再安全,仅用于兼容或校验场景,不要用于密码或签名。
关键区别:
- MD5 输出长度:16 字节;SHA256:32 字节
- 对应宏:
EVP_md5()/EVP_sha256() - 缓冲区大小要匹配(
unsigned char md[32]对 SHA256,[16]对 MD5)
4. 常见坑和提醒
避免踩这些雷:
- 忘记检查
EVP_DigestInit_ex返回值(失败返回 0) - 传入空指针给
EVP_DigestUpdate且长度非零(崩溃) - 用完不
EVP_MD_CTX_free→ 内存泄漏(尤其循环中) - 误以为
EVP_DigestFinal_ex会自动以 null 结尾 —— 它只写二进制,转 hex 需手动格式化 - 在多线程中复用同一个
EVP_MD_CTX*→ 必须每个线程独立创建
基本上就这些。EVP 接口统一、安全、可扩展,以后换成 SHA512 也只需改一行。










