在 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版.戚正伟,译.北京:人民邮电出版社 ↩