Java獲取文件的hash值(SHA256)兩種方式
簡(jiǎn)介
在工作開(kāi)發(fā)當(dāng)中需求要通過(guò)文件的hash值比對(duì)文件是否被篡改過(guò),于是通過(guò)使用了(sha256)hash值進(jìn)行比對(duì),因?yàn)閷?duì)于任意長(zhǎng)度的消息,SHA256都會(huì)產(chǎn)生一個(gè)256bit長(zhǎng)的哈希值,通常用一個(gè)長(zhǎng)度為64的十六進(jìn)制字符串來(lái)表示。
獲取網(wǎng)絡(luò)文件的sha256值(方式一)
首先通過(guò)InputStream獲取網(wǎng)絡(luò)URL文件,然后創(chuàng)建臨時(shí)文件,再通過(guò)FileInputStream以字節(jié)流的方式逐塊讀取文件內(nèi)容,然后通過(guò)DigestInputStream將讀取的數(shù)據(jù)傳遞給MessageDigest來(lái)計(jì)算SHA256哈希值。這樣可以避免將整個(gè)文件加載到內(nèi)存中,而是通過(guò)緩沖區(qū)逐塊處理文件內(nèi)容。
JAVA代碼如下:(文件地址自己改一下)
/**
* 計(jì)算SHA256哈希值
* @param filePath 文件路徑
* @return 字節(jié)數(shù)組
* @throws IOException IO異常
* @throws NoSuchAlgorithmException NoSearch算法異常
*/
public static byte[] calculateSHA256(String filePath) throws IOException, NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
//獲取網(wǎng)絡(luò)URL文件
InputStream fis2 = new URL(filePath).openStream();
//創(chuàng)建臨時(shí)文件
File file = File.createTempFile(IdWorker.getIdStr(),"");
FileUtil.writeFromStream(fis2,file);
try (
FileInputStream fis = new FileInputStream(file);
FileChannel channel = fis.getChannel();
DigestInputStream dis = new DigestInputStream(fis, digest)) {
ByteBuffer buffer = ByteBuffer.allocate(8192); // 8 KB buffer
while (channel.read(buffer) != -1) {
buffer.flip();
digest.update(buffer);
buffer.clear();
}
return digest.digest();
}
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換為String類型哈希值
* @param bytes 字節(jié)數(shù)組
* @return 哈希值
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
public static void main(String[] args) {
String filePath = "https://xxxxx/20230410/bfd71f584d9645b0a5e3d7a465119f0c.pdf";
try {
byte[] sha256 = calculateSHA256(filePath);
String sha256Hex = bytesToHex(sha256);
System.out.println("SHA256: " + sha256Hex);
} catch (IOException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
}響應(yīng)結(jié)果:(這里的結(jié)果是我自己再測(cè)試的時(shí)候生成的)
SHA256: cffebd06c485d17b8a93308e1e39cc4c1636444b762c9c153ba8b29022392b98
獲取本地文件的sha256值(方式二)
通過(guò)FileInputStream以字節(jié)流的方式逐塊讀取文件內(nèi)容,然后通過(guò)DigestInputStream將讀取的數(shù)據(jù)傳遞給MessageDigest來(lái)計(jì)算SHA256哈希值。這樣可以避免將整個(gè)文件加載到內(nèi)存中,而是通過(guò)緩沖區(qū)逐塊處理文件內(nèi)容。
JAVA代碼如下:(文件地址自己改一下)
/**
* 計(jì)算SHA256哈希值
* @param filePath 文件路徑
* @return 字節(jié)數(shù)組
* @throws IOException IO異常
* @throws NoSuchAlgorithmException NoSearch算法異常
*/
public static byte[] calculateSHA256(String filePath) throws IOException, NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
try (
FileInputStream fis = new FileInputStream(filePath);
FileChannel channel = fis.getChannel();
DigestInputStream dis = new DigestInputStream(fis, digest)) {
ByteBuffer buffer = ByteBuffer.allocate(8192); // 8 KB buffer
while (channel.read(buffer) != -1) {
buffer.flip();
digest.update(buffer);
buffer.clear();
}
return digest.digest();
}
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換為String類型哈希值
* @param bytes 字節(jié)數(shù)組
* @return 哈希值
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
public static void main(String[] args) {
String filePath = "D:\\bfd71f584d9645b0a5e3d7a465119f0c.pdf";
try {
byte[] sha256 = calculateSHA256(filePath);
String sha256Hex = bytesToHex(sha256);
System.out.println("SHA256: " + sha256Hex);
} catch (IOException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
}響應(yīng)結(jié)果:(這里的結(jié)果是我自己再測(cè)試的時(shí)候生成的)
SHA256: cffebd06c485d17b8a93308e1e39cc4c1636444b762c9c153ba8b29022392b98
總結(jié)
到此這篇關(guān)于Java獲取文件的hash值(SHA256)兩種方式的文章就介紹到這了,更多相關(guān)Java獲取文件hash值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談springboot @Repository與@Mapper的區(qū)別
本文主要介紹了淺談springboot @Repository與@Mapper的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Quarkus中RESTEasy?Reactive集成合并master分支
這篇文章主要為大家介紹了Quarkus中RESTEasy?Reactive集成合并master分支的詳細(xì)作用分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
Springboot升級(jí)至2.4.0中出現(xiàn)的跨域問(wèn)題分析及修改方案
這篇文章主要介紹了Springboot升級(jí)至2.4.0中出現(xiàn)的跨域問(wèn)題分析及修改方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Java實(shí)現(xiàn)簡(jiǎn)單字符生成器代碼例子
這篇文章主要介紹了Java實(shí)現(xiàn)簡(jiǎn)單字符生成器代碼例子,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06

