如何快速获取已安装应用的.apk哈希值?现有方案耗时26秒求优化
首先直接给你结论:APK文件的头部(本质是ZIP文件头)并没有预计算好的整个APK的哈希值。APK基于ZIP格式,ZIP规范里只存储了归档内单个文件的CRC32校验值,没有整个APK文件的全局哈希,所以你没办法直接从头部读取现成的结果,还是得通过计算获取,但我们可以从流程上大幅优化速度,把26秒的耗时降下来。
下面是几个实用的优化方向:
流式计算哈希,避免全量加载到内存
你当前的put_content_into_buffer是把整个APK读进内存再计算,这不仅占用大量内存,还会因为内存拷贝、大对象处理拖慢速度。改成流式处理:用FileInputStream(或更高效的FileChannel)逐块读取APK文件,同时喂给哈希计算函数(比如Java的MessageDigest),边读边算,不用把整个文件存进内存。这种方式能减少IO和内存操作的开销,速度提升非常明显。利用文件元信息做增量计算
如果你的场景是定期校验APK哈希,没必要每次都全量计算。可以记录上次计算的哈希值,同时保存APK文件的修改时间、文件大小这两个元信息。下次校验时先对比这两个元信息,只有当它们变化时,才重新计算哈希——大部分情况下,APK不会频繁更新,这样能省掉90%以上的计算耗时。选择更轻量的哈希算法(如果业务允许)
哈希算法的计算速度差异很大:MD5的计算速度比SHA-256快2-3倍,SHA-1也比SHA-256快不少。如果你的业务场景不需要强加密级别的哈希(比如只是用来做APK完整性校验,而非安全校验),可以考虑换成MD5;如果必须用SHA系列,优先选SHA-1而非SHA-256/512。缓存计算结果
把计算好的APK哈希和对应的包名、版本号绑定,存在本地数据库或者SharedPreferences里。下次需要获取该APK的哈希时,直接从缓存读取即可,只有当APK版本更新或者文件被修改时,再重新计算并更新缓存。优化文件读取路径
已安装APK的路径在Android里是/data/app/[包名]/base.apk,有些设备可能会有优化后的副本,但直接读取原APK文件是最可靠的。另外,尽量用原生的文件读取API(比如NIO的FileChannel),比Java IO的InputStream在大文件读取上效率更高。
补充一点:Android系统里的PackageManager能获取到APK的签名信息,但签名哈希和整个APK的哈希是两回事——签名哈希只验证签名部分的完整性,不代表整个APK文件的哈希,所以不能用来替代你需要的APK文件哈希。
内容的提问来源于stack exchange,提问作者specter987

