/**
* 读取指定文件块数据Sha1
*
* @param fis
* @return
*/
private static MessageDigest calSha1(BufferedInputStream fis) {
MessageDigest sha1 = null;
try {
byte[] buffer = new byte[1024];
int numRead = 0;
int total = 0;
sha1 = MessageDigest.getInstance("SHA-1");
while ((numRead = fis.read(buffer)) > 0) {
sha1.update(buffer, 0, numRead);
total += numRead;
if (total >= BLOCK_SIZE) {//每次最多读入4M
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sha1;
}
/**
* 获取hash/etag,根据File文件计算hash值
*
* @param file 文件
* @return
*/
public static String getEtagHash(File file) {
String etagHash = null;
BufferedInputStream fis = null;
try {
if (file.exists()) {
byte[] ret = new byte[21];
long blockCount = blockCount(file.length());
fis = new BufferedInputStream(new FileInputStream(file));
if (blockCount <= 1) { // 文件块数小于等于1块
MessageDigest sha1 = calSha1(fis);
if (null != sha1) {
byte[] input = sha1.digest();
ret[0] = BYTE_LOW_4;
for (int i = 0; i < 20; ++i) {//SHA1算法位20字节
ret[i + 1] = input[i];
}
}
} else {//将所有sha1值按切块顺序拼接
byte[] rec = new byte[(int) blockCount * 20];
ret[0] = BYTE_OVER_4;
int i, cnt = 0;
for (i = 0; i < blockCount; i++) {//每块文件分别计算sha1
MessageDigest sha1 = calSha1(fis);
if (null != sha1) {
byte[] tmp = sha1.digest();
for (int j = 0; j < 20; j++) {
rec[cnt++] = tmp[j];
}
}
}
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");//对拼接好的数据再做sha1计算
sha1.update(rec, 0, (int) blockCount * 20);
byte[] tmp = sha1.digest();
for (i = 0; i < 20; ++i) {//在最前面拼上单个字节,值为0x96
ret[i + 1] = tmp[i];
}
}
etagHash = EncodeUtils.urlsafeEncodeString(ret);
} else {
System.out.println("File[" + file.getAbsolutePath() + "] Not Exist,Cannot Calculate Hash!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
fis = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return etagHash;
}