最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java關(guān)于MD5文件校驗問題處理

 更新時間:2026年03月30日 09:42:43   作者:Pisces_224  
文章主要介紹了Java獲取文件MD5值的五種方法,包括原始讀入內(nèi)存、分多次讀入、使用字節(jié)數(shù)組轉(zhuǎn)十六進制字符串、利用commons-codec包等,并解釋了MD5算法原理、用途及安全性,最后提供了驗證生成MD5值正確性的方法

前言

JAVA中獲取文件MD5值的四種方法其實都很類似,因為核心都是通過JAVA自帶的MessageDigest類來實現(xiàn)。

獲取文件MD5值主要分為三個步驟,第一步獲取文件的byte信息,第二步通過MessageDigest類進行MD5加密,第三步轉(zhuǎn)換成16進制的MD5碼值。

什么是MD5算法

MD5訊息摘要演算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼雜湊函數(shù),可以產(chǎn)生出一個128位元(16位元組)的散列值(hash value),用于確保信息傳輸完整一致。

原理

MD5是一種不可逆的算法,是一種散列函數(shù),使用的是hash算法。輸入任意長度的信息,經(jīng)過處理,輸出為128位的信息(數(shù)字指紋),不同的輸入得到的不同的結(jié)果(唯一性)。

在計算過程中原文的部分信息是丟失了的。所以不能從密文(散列值)反過來得到原文,即沒有解密算法。

MD5相當(dāng)于超損壓縮。

MD5用途

1.防止被篡改:

1)比如發(fā)送一個電子文檔,發(fā)送前,我先得到MD5的輸出結(jié)果a。然后在對方收到電子文檔后,對方也得到一個MD5的輸出結(jié)果b。如果a與b一樣就代表中途未被篡改。

2)比如我提供文件下載,為了防止不法分子在安裝程序中添加木馬,我可以在網(wǎng)站上公布由安裝文件得到的MD5輸出結(jié)果。

3)SVN在檢測文件是否在CheckOut后被修改過,也是用到了MD5.

2.防止直接看到明文:

  • 現(xiàn)在很多網(wǎng)站在數(shù)據(jù)庫存儲用戶的密碼的時候都是存儲用戶密碼的MD5值。這樣就算不法分子得到數(shù)據(jù)庫的用戶密碼的MD5值,也無法知道用戶的密碼。(比如在UNIX系統(tǒng)中用戶的密碼就是以MD5(或其它類似的算法)經(jīng)加密后存儲在文件系統(tǒng)中。
  • 當(dāng)用戶登錄的時候,系統(tǒng)把用戶輸入的密碼計算成MD5值,然后再去和保存在文件系統(tǒng)中的MD5值進行比較,進而確定輸入的密碼是否正確。通過這樣的步驟,系統(tǒng)在并不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統(tǒng)的合法性。
  • 這不但可以避免用戶的密碼被具有系統(tǒng)管理員權(quán)限的用戶知道,而且還在一定程度上增加了密碼被破解的難度。)

3.防止抵賴(數(shù)字簽名):

  • 這需要一個第三方認證機構(gòu)。例如A寫了一個文件,認證機構(gòu)對此文件用MD5算法產(chǎn)生摘要信息并做好記錄。
  • 若以后A說這文件不是他寫的,權(quán)威機構(gòu)只需對此文件重新產(chǎn)生摘要信息,然后跟記錄在冊的摘要信息進行比對,相同的話,就證明是A寫的了。這就是所謂的“數(shù)字簽名”。

MD5安全性

普遍認為MD5是很安全,因為暴力.破.解的時間是一般人無法接受的。實際上如果把用戶的密碼MD5處理后再存儲到數(shù)據(jù)庫,其實是很不安全的。因為用戶的密碼是比較短的,而且很多用戶的密碼都使用生日,手機號碼,身份證號碼,電話號碼等等?;蛘呤褂贸S玫囊恍┘臄?shù)字,或者某個英文單詞。

如果我把常用的密碼先MD5處理,把數(shù)據(jù)存儲起來,然后再跟你的MD5結(jié)果匹配,這時我就有可能得到明文。

現(xiàn)在大多數(shù)網(wǎng)站密碼的策略是強制要求用戶使用數(shù)字大小寫字母的組合的方式提高用戶密碼的安全度。

方法

方法一

較為原始,將文件一次性讀入內(nèi)存,然后通過MessageDigest進行MD5加密,最后再手動將其轉(zhuǎn)換為16進制的MD5值。

private final static String[] strHex = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    public static String getMD5One(String path) {
        StringBuffer sb = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = md.digest(FileUtils.readFileToByteArray(new File(path)));
            for (int i = 0; i < b.length; i++) {
                int d = b[i];
                if (d < 0) {
                    d += 256;
                }
                int d1 = d / 16;
                int d2 = d % 16;
                sb.append(strHex[d1] + strHex[d2]);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

方法二

借助了Integer類的方法實現(xiàn)16進制的轉(zhuǎn)換,比方法一更簡潔一些。

PS:JAVA中byte是有負數(shù)的,代碼中&0xff的操作與計算機中數(shù)據(jù)存儲的原理有關(guān),即負數(shù)存儲的是二進制的補碼。

public static String getMD5Two(String path) {
        StringBuffer sb = new StringBuffer("");
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(FileUtils.readFileToByteArray(new File(path)));
            byte b[] = md.digest();
            int d;
            for (int i = 0; i < b.length; i++) {
                d = b[i];
                if (d < 0) {
                    d = b[i] & 0xff;
                    // 與上一行效果等同
                    // i += 256;
                }
                if (d < 16)
                    sb.append("0");
                sb.append(Integer.toHexString(d));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

方法三

本方法在讀入文件信息上有點不同。這里是分多次將一個文件讀入,對于大型文件而言,比較推薦這種方式,占用內(nèi)存比較少。

步驟三則是通過BigInteger類提供的方法進行16進制的轉(zhuǎn)換。

public static String getMD5Three(String path) {
        BigInteger bi = null;
        try {
            byte[] buffer = new byte[8192];
            int len = 0;
            MessageDigest md = MessageDigest.getInstance("MD5");
            File f = new File(path);
            FileInputStream fis = new FileInputStream(f);
            while ((len = fis.read(buffer)) != -1) {
                md.update(buffer, 0, len);
            }
            fis.close();
            byte[] b = md.digest();
            bi = new BigInteger(1, b);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bi.toString(16);
    }

方法四

通過調(diào)用 字節(jié)數(shù)組轉(zhuǎn)十六進制字符串的方法 實現(xiàn)(跟方法3差不多)

public static String getMD5Four(String filePath) {

        try {
            InputStream fis = new FileInputStream(filePath); // FileNotFoundException
            MessageDigest md = MessageDigest.getInstance("MD5"); // NoSuchAlgorithmException
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {  // IO exception
                md.update(buffer, 0, length);
            }
            fis.close();
            // 轉(zhuǎn)換并返回包含16個元素字節(jié)數(shù)組,返回數(shù)值范圍為-128到127
            byte[] md5Bytes = md.digest();
            // 方法2 使用bigInteger
//            BigInteger bigInteger = new BigInteger(1, md5Bytes);
//            return bigInteger.toString(16);
            // 方法3  使用字節(jié)數(shù)組轉(zhuǎn)十六進制字符串
            String strMd5 = bytesToHexStr(md5Bytes);
            return strMd5;


        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return "";
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 字節(jié)數(shù)組轉(zhuǎn)十六進制字符串
     * @param b 字節(jié)數(shù)組
     * @return 十六進制字符串
     */
    public static String bytesToHexStr(byte[] b) {
        StringBuilder strBuilder = new StringBuilder();
        String strTemp = "";
        for (int n = 0; n < b.length; ++n) {
            strTemp = (Integer.toHexString(b[n] & 0XFF));
            if (strTemp.length() == 1) {
                strBuilder.append("0").append(strTemp);
            } else {
                strBuilder.append(strTemp);
            }
        }
        return strBuilder.toString();
    }

方法五

最簡單~

JAVA自帶的commons-codec包就提供了獲取16進制MD5值的方法。其底層實現(xiàn)上,也是分多次將一個文件讀入,類似方法三、四

DigestUtils.md5Hex(new FileInputStream(path));

另外,如何知道自己生成的文件md5值是否正確?

cmd 輸入 powershell 切入到powershell面板

certutil -hashfile “./xxx.txt” MD5    # (MD5需大寫)

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot讀取文件,打成jar包后訪問不到的解決

    springboot讀取文件,打成jar包后訪問不到的解決

    這篇文章主要介紹了springboot讀取文件,打成jar包后訪問不到的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解spring boot jpa整合QueryDSL來簡化復(fù)雜操作

    詳解spring boot jpa整合QueryDSL來簡化復(fù)雜操作

    這篇文章主要介紹了詳解spring boot jpa整合QueryDSL來簡化復(fù)雜操作,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java從入門到起飛之變量與運算符詳解

    Java從入門到起飛之變量與運算符詳解

    這篇文章主要介紹了Java編程語言中的關(guān)鍵字、標識符、變量、基本數(shù)據(jù)類型以及運算符等基本概念和用法,它涵蓋了變量聲明、賦值、類型轉(zhuǎn)換、字符串操作以及運算符優(yōu)先級等內(nèi)容,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-03-03
  • Spring?Boot?詳細分析Conditional自動化配置注解

    Spring?Boot?詳細分析Conditional自動化配置注解

    首先我們先了解一下@Conditional注解,@Conditional是Spring4新提供的注解,它的作用是按照一定的條件進行判斷,需要注入的Bean滿足給定條件才可以注入到Spring?IOC容器中
    2022-07-07
  • SpringBoot基本web開發(fā)demo過程解析

    SpringBoot基本web開發(fā)demo過程解析

    這篇文章主要介紹了SpringBoot基本web開發(fā)demo過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • 解決spring項目找不到Aspect依賴注解的問題

    解決spring項目找不到Aspect依賴注解的問題

    這篇文章主要介紹了解決spring項目找不到Aspect依賴注解的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java使用poi自定義excel標題頭并導(dǎo)出方式

    java使用poi自定義excel標題頭并導(dǎo)出方式

    這篇文章主要介紹了java使用poi自定義excel標題頭并導(dǎo)出方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Kotlin 的注解類詳解及實例

    Kotlin 的注解類詳解及實例

    這篇文章主要介紹了Kotlin 的注解類詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java SpringMVC自學(xué)自講

    Java SpringMVC自學(xué)自講

    本篇文章主要介紹了java SpringMVC——如何獲取請求參數(shù)詳解,詳細的介紹了每種參數(shù)注解的用法及其實例。感興趣的小伙伴們可以參考一下
    2021-09-09
  • mybatis?plus框架@TableField注解不生效問題及解決方案

    mybatis?plus框架@TableField注解不生效問題及解決方案

    最近遇到一個mybatis plus的問題,@TableField注解不生效,導(dǎo)致查出來的字段反序列化后為空,今天通過本文給大家介紹下mybatis?plus框架的@TableField注解不生效問題總結(jié),需要的朋友可以參考下
    2022-03-03

最新評論

积石山| 遂昌县| 沁阳市| 福安市| 礼泉县| 临洮县| 康平县| 阿荣旗| 吉首市| 岳西县| 裕民县| 博爱县| 巴里| 沈阳市| 肥东县| 沙湾县| 兴安县| 思茅市| 名山县| 长寿区| 临沭县| 台东市| 建宁县| 家居| 太仆寺旗| 阜城县| 伊宁市| 吴桥县| 阿勒泰市| 纳雍县| 枝江市| 瑞昌市| 衢州市| 全椒县| 泸定县| 临桂县| 腾冲县| 蕉岭县| 广元市| 南开区| 邹平县|