package parser.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 获取字符串或文件的哈希值
*/
public class HashTool {
/**
* 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符, apache校验下载的文件的正确性用的就是默认的这个组合
*/
protected final static char hexDigits[] = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/**
* 计算文件 MD5
*
* @param file 文件
* @throws java.io.IOException
*/
public static String getMD5(File file) throws IOException {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
InputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[4096];
int numRead;
while ((numRead = inputStream.read(buffer)) > 0) {
if (messageDigest != null) {
messageDigest.update(buffer, 0, numRead);
} else {
throw new IOException("MessageDigest is NULL!");
}
}
inputStream.close();
if (messageDigest != null) {
byte[] bytes = messageDigest.digest();
return bytesToHex(bytes);
} else {
throw new IOException("MessageDigest is NULL!");
}
}
/**
* 计算文件 SHA256
*
* @param file 文件
* @throws java.io.IOException
*/
public static String getSHA256(File file) throws IOException {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
InputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[4096];
int numRead;
while ((numRead = inputStream.read(buffer)) > 0) {
if (messageDigest != null) {
messageDigest.update(buffer, 0, numRead);
} else {
throw new IOException("MessageDigest is NULL!");
}
}
inputStream.close();
if (messageDigest != null) {
byte[] bytes = messageDigest.digest();
return bytesToHex(bytes);
} else {
throw new IOException("MessageDigest is NULL!");
}
}
/**
* 计算字节数组的 md5
*
* @param aData 字节数组
*/
public static String getMD5(byte[] aData) throws IOException {
MessageDigest messagedigest = null;
try {
messagedigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (messagedigest != null) {
messagedigest.update(aData);
return bufferToHex(messagedigest.digest());
} else {
throw new IOException("MessageDigest is NULL!");
}
}
/**
* 计算字节数组的 md5
*
* @param aData 字节数组
*/
public static String getSHA256(byte[] aData) throws IOException {
MessageDigest messagedigest = null;
try {
messagedigest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (messagedigest != null) {
messagedigest.update(aData);
return bytesToHex(messagedigest.digest());
} else {
throw new IOException("MessageDigest is NULL!");
}
}
private static String bytesToHex(byte[] bytes) {
String str = "";
String tmp;
for (byte aByte : bytes) {
tmp = Integer.toHexString(aByte & 0xFF);
if (tmp.length() == 1) {
str += "0";
}
str += tmp;
}
return str;
}
/**
* 16进制转字符串
*
* @param data 字节数组
* @return 字符串
*/
static public String hex2Str(byte[] data) {
final String HEX = "0123456789ABCDEF";
final StringBuilder sb = new StringBuilder();
for (final byte b : data) {
sb.append(HEX.charAt((b >> 4) & 0x0F));
sb.append(HEX.charAt(b & 0x0F));
}
return sb.toString();
}
private static String bufferToHex(byte bytes[]) {
return bytes2Hex(bytes, 0, bytes.length);
}
private static String bytes2Hex(byte bytes[], int m, int n) {
StringBuffer stringbuffer = new StringBuffer(2 * n);
int k = m + n;
for (int l = m; l < k; l++) {
appendHexPair(bytes[l], stringbuffer);
}
return stringbuffer.toString();
}
private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>>
// 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
stringbuffer.append(c0);
stringbuffer.append(c1);
}
}