在 GNU/Linux 中用 C语言计算文件的 Hash
在 GNU/Linux 中用 C语言计算文件的 Hash
在今日之前,笔者从未想到使用 C/C++ 在 GNU/Linux 计算文件的 Hash (例如:SHA-1、MD5 、 SHA-256 等)会这样的麻烦.
笔者以为会有 char * sha256sum(int fd) 或 char * sha256sum(FILE *stream) 类似的函数来轻松的获取文件的 Hash .但事实并非如此,获取文件的 Hash 的方法远比笔者想象中的做法要复杂.
方案1 自行实现Hash函数
这种方案是最为麻烦的,但有着不依赖第三方库和程序的优点.至于如何实现 Hash 函数不是本文重点,笔者对此也不做说明.
方案2 调用Openssl 库
笔者的 openssl 版本为1.1.1i 8 Dec 2020 , /usr/include/openssl 中提供的头文件可点击下方的小三角查看.
点此查看更多信息
aes.h asn1err.h asn1.h asn1_mac.h asn1t.h asyncerr.h async.h bioerr.h bio.h blowfish.h bnerr.h bn.h buffererr.h buffer.h camellia.h cast.h cmac.h cmserr.h cms.h comperr.h comp.h conf_api.h conferr.h conf.h cryptoerr.h crypto.h cterr.h ct.h des.h dherr.h dh.h dsaerr.h dsa.h dtls1.h ebcdic.h ecdh.h ecdsa.h ecerr.h ec.h engineerr.h engine.h e_os2.h err.h evperr.h evp.h hmac.h idea.h kdferr.h kdf.h lhash.h md2.h md4.h md5.h mdc2.h modes.h objectserr.h objects.h obj_mac.h ocsperr.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem2.h pemerr.h pem.h pkcs12err.h pkcs12.h pkcs7err.h pkcs7.h rand_drbg.h randerr.h rand.h rc2.h rc4.h rc5.h ripemd.h rsaerr.h rsa.h safestack.h seed.h sha.h srp.h srtp.h ssl2.h ssl3.h sslerr.h ssl.h stack.h storeerr.h store.h symhacks.h tls1.h tserr.h ts.h txt_db.h uierr.h ui.h whrlpool.h x509err.h x509.h x509v3err.h x509v3.h x509_vfy.h1 |
|
本方案调用了 openssl 提供的 sha.h 比自行实现 Hash函数 能方便一点点.使用本方案的程序在编译时需要使用 -lssl 和 -lcrypto 参数链接相关的库.
方案3 进程间通信调用其他程序
在 GNU/Linux 中通常含有 sha256sum 、 sha512sum 、 md5sum 等程序,并支持以类似 sha256sum <path> 的格式直接调用.那么,就可以使用 popen 函数完成进程间通信,直接获取文件的 Hash .
1 |
|
这种方式的好处显而易见「方便」,这种方法是也最容易理解的.
值得多说一句的是:Hash 函数生成的 Hash 是一个由函数决定的常数(例如:SHA-256的结果以字符串输出有 64 个 可打印字符 ),这个特性使得 数组的长度 与 读取的输出长度 是确定的.
测试环境
OS : Arch Linux
Kernel : 5.9.14-arch1-1
openssl : 1.1.1i 8 Dec 2020
gcc : 10.2.0
参考资料
1. W.RichardStevens.Stephen.UNIX环境高级编程[M].第3版.戚正伟,译.北京:人民邮电出版社 ↩
在 GNU/Linux 中用 C语言计算文件的 Hash