文件的摘要算法(md5、sm3、sha256、crc)
为了校验文件在传输中保证完整性和准确性,因此需要发送方先对源文件产生一个校验码,并将该值传输给接收方,将附件通过ftph或http方式传输后,由接收方使用相同的算法对接收文件再获取一个新的校验码,将该值和发送方传的校验码进行对比。本文会提供四种算法来生成该校验码,包括:md5、sm3、sha256、crc,其中md5执行速度最快,但是会发生2个文件生成校验码一样的情况(很少发生,项目实际几乎没遇到过),sm3是国密的方式,现在信创系统比较推荐的,sha256我只在集成区块链的项目时遇到过(文件上链一般需要md5和sha256两个值),crc是数据块的多项式除法余数来生成一个固定长度的校验码(在linux环境可以用cksum 路径来生成)
package com;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.zip.CRC32;
/**
* commons-codec-1.10.jar
* commons-io-2.8.0.jar
* bcprov-jdk15on-1.59.jar
*
*/
public class Test {
static Logger logger = LoggerFactory.getLogger(Test.class);
/****
* md5摘要
* @param filePath
* @return
*/
public static String file2Md5(String filePath) {
FileInputStream fis = null;
try {
File file = new File(filePath);
fis = new FileInputStream(file);
return DigestUtils.md5Hex(fis);
}catch (Exception e){
logger.error("获取文件md5异常:"+filePath,e);
return "";
}finally {
IOUtils.closeQuietly(fis);
}
}
/****
* sm3摘要
* bcpov-jdk15on-1.59.jar
*/
public static String file2Sm3(String filePath){
File file = new File(filePath);
FileInputStream fis = null;
try{
fis = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(fis);
SM3Digest sm3Digest = new SM3Digest();
sm3Digest.update(bytes,0,bytes.length);
byte bt[] = new byte[sm3Digest.getDigestSize()];
sm3Digest.doFinal(bt, 0);
return ByteUtils.toHexString(bt);
}catch(Exception e){
logger.error("获取文件sm3异常:"+filePath,e);
return "";
}finally {
IOUtils.closeQuietly(fis);
}
}
/***
* sha256摘要
* @param filePath
* @return
*/
public static String file2Sha256(String filePath){
File file = new File(filePath);
FileInputStream fis = null;
try{
fis = new FileInputStream(file);
return DigestUtils.sha256Hex(fis);
}catch (Exception e){
logger.error("获取文件sha256异常:"+filePath,e);
return "";
}finally{
IOUtils.closeQuietly(fis);
}
}
/****
* 循环冗余校验
* @param filePath
* @return
*/
public static String file2Crc32(String filePath) {
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(filePath);
bis = new BufferedInputStream(fis);
CRC32 crc32 = new CRC32();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
crc32.update(buffer, 0, bytesRead);
}
return String.valueOf(crc32.getValue());
} catch (Exception e) {
logger.error("获取文件crc异常:"+filePath,e);
return "";
}finally {
IOUtils.closeQuietly(bis);
IOUtils.closeQuietly(fis);
}
}
}