JAVA 获取文件指纹

一、使用场景
  • 检测文件是否被篡改:
    在文件上传到服务器的时候,我们希望能够获得文件的指纹以确定文件没有被篡改过

  • 不存储重复文件信息:
    在文件上传到服务器的时候,为了节省服务器的存储空间,我们可以对文件指纹进行比对,存在的指纹文件,无需再次保存到文件服务器

二、加密算法
  1. 常用哈希算法:

    • MD4 1990 年,输出 128 位(已经不安全)
    • MD5 1991 年,输出 128 位(已经不安全)
    • SHA-0 1993 年 输出 160 位(发布之后很快就被 NSA 撤回,是 SHA-1 的前身)
    • SHA-1 1995 年,输出 160 位(已经不安全)
    • SHA-2 包括:SHA-224SHA-256SHA-384SHA-512,分别输出 224、256、384、512 位(目前安全)
  2. 哈希算法特点:

    • 正像快速:原始数据可以快速计算出哈希值
    • 逆向困难:通过哈希值基本不可能推导出原始数据
    • 输入敏感:原始数据只要有一点变动,得到的哈希值差别很大
    • 冲突避免:很难找到不同的原始数据得到相同的哈希值
三、源码演示
  1. 获取目标文件

    /**
     * 读取本地文件到比特数组
     *
     * @param	file    文件对象
     * @return  byte[]  文件数组
     */
    public static byte[] readRandomAccess(File file) throws IOException {
        // 1、使用 RandomAccessFile 打开文件管道
        FileChannel channel = new RandomAccessFile(file, "r").getChannel();
        int fileSize = (int) channel.size();
        try {
            // 2、创建 MappedByteBuffer,并使用 NIO 管道进行数据映射,加载数据到物理内存
            //load(): 将此缓冲区的内容加载到物理内存中。此方法尽最大努力确保当它返回时,缓冲区的内容驻留在物理内存中。调用此方法可能会导致出现一些页面错误和I/O操作。
            MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, fileSize).load();
            //remaining() 返回当前位置和限制之间的元素数。此缓冲区中剩余的元素数
            byte[] result = new byte[fileSize];
            if (buffer.remaining() > 0) {
                // 3、读取数据到 byte 数组中
                buffer.get(result, 0, fileSize);
            }
            buffer.clear();
            return result;
        } finally {
            closeChannel(channel);
        }
    }
    
    private static void closeChannel(FileChannel channel) {
        try {
            channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }    
    
  2. 采用 MD5 哈希

    /**
     * 生成文件 MD5 指纹
     *
     * @param	fileData            文件内容比特数组
     * @return  java.lang.String    文件内容 MD5 指纹
     */
    public static String generateFileMd5Hash(byte[] fileData) {
        return DigestUtils.md5Hex(fileData);
    }
    

    P.S

    DigestUtils.md5Hex 有很多重载,可以根据实际情况选择

  3. 采用 SHA 哈希

    /**
     * 生成文件 SHA 指纹
     *
     * @param	fileData            文件内容比特数组
     * @return  java.lang.String    文件内容 SHA 指纹
     */
    public static String generateFileSha256Hash(byte[] fileData) {
        return DigestUtils.sha256Hex(fileData);
    }
    

    P.S

    DigestUtils.sha256Hex 有很多重载,可以根据实际情况选择

  4. 演示结果

    public static void main(String[] args) throws IOException {
        File file = new File("/Users/rambo/Desktop/1.txt");
        byte[] bytes = readRandomAccess(file);
        String md5Hash = generateFileMd5Hash(bytes);
        String shaHash = generateFileSha256Hash(bytes);
        System.out.println("MD5 指纹:" + md5Hash);
        System.out.println("SHA 指纹:" + shaHash);
    }
    
    MD5 指纹:0615ce4d9d3c12bf493bab656dd65dd0
    SHA 指纹:b1f63d223f7c733b62243d7f55961ab4ad38d92ec413a03c7bed51288aa22323
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值