- 新增 ClientController,支持已绑定设备的信息、定位、应用与截图查询 - JWT 增加 clientType 标识,实现 admin/client 端鉴权隔离 - client 端支持独立配置令牌有效期,并在刷新时按端解析 TTL - 截图列表仅返回最近 20 条并规范化访问 URL 前缀
155 lines
5.6 KiB
Java
155 lines
5.6 KiB
Java
package com.youlai.boot.common.util;
|
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
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 HashUtils {
|
|
|
|
public static String calculateMultipartFileMd5(MultipartFile file) throws NoSuchAlgorithmException, IOException {
|
|
MessageDigest digest = MessageDigest.getInstance("MD5");
|
|
// 使用try-with-resources自动管理输入流
|
|
try (InputStream inputStream = file.getInputStream()) {
|
|
byte[] buffer = new byte[4096]; // 统一缓冲区大小为4KB
|
|
int bytesRead;
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
digest.update(buffer, 0, bytesRead);
|
|
}
|
|
}
|
|
byte[] hashBytes = digest.digest();
|
|
return bytesToHex(hashBytes); // 复用现有工具方法
|
|
}
|
|
|
|
/**
|
|
* 计算 MultipartFile 的 SHA1 哈希值
|
|
*
|
|
* @param file 上传的文件
|
|
* @return SHA1 哈希值(小写十六进制字符串)
|
|
* @throws NoSuchAlgorithmException 算法不存在异常
|
|
* @throws IOException IO异常
|
|
*/
|
|
public static String calculateMultipartFileSha1(MultipartFile file) throws NoSuchAlgorithmException, IOException {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
|
try (InputStream inputStream = file.getInputStream()) {
|
|
byte[] buffer = new byte[4096];
|
|
int bytesRead;
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
digest.update(buffer, 0, bytesRead);
|
|
}
|
|
}
|
|
byte[] hashBytes = digest.digest();
|
|
return bytesToHex(hashBytes);
|
|
}
|
|
|
|
/**
|
|
* 计算 MultipartFile 的 SHA256 哈希值
|
|
*
|
|
* @param file 上传的文件
|
|
* @return SHA256 哈希值(小写十六进制字符串)
|
|
* @throws NoSuchAlgorithmException 算法不存在异常
|
|
* @throws IOException IO异常
|
|
*/
|
|
public static String calculateMultipartFileSha256(MultipartFile file) throws NoSuchAlgorithmException, IOException {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
try (InputStream inputStream = file.getInputStream()) {
|
|
byte[] buffer = new byte[4096];
|
|
int bytesRead;
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
digest.update(buffer, 0, bytesRead);
|
|
}
|
|
}
|
|
byte[] hashBytes = digest.digest();
|
|
return bytesToHex(hashBytes);
|
|
}
|
|
|
|
public static String getFileMD5(File file) throws NoSuchAlgorithmException, IOException {
|
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
|
FileInputStream fis = new FileInputStream(file);
|
|
byte[] dataBytes = new byte[1024];
|
|
|
|
int bytesRead;
|
|
while ((bytesRead = fis.read(dataBytes)) != -1) {
|
|
md.update(dataBytes, 0, bytesRead);
|
|
}
|
|
|
|
byte[] mdBytes = md.digest();
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
for (byte mdByte : mdBytes) {
|
|
sb.append(Integer.toString((mdByte & 0xff) + 0x100, 16).substring(1));
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
public static String calculateSHA1(File file) throws NoSuchAlgorithmException, IOException {
|
|
InputStream inputStream = new FileInputStream(file);
|
|
return calculateSHA1(inputStream);
|
|
}
|
|
|
|
public static String calculateSHA1(InputStream inputStream) throws NoSuchAlgorithmException, IOException {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
|
byte[] buffer = new byte[4096];
|
|
int bytesRead;
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
digest.update(buffer, 0, bytesRead);
|
|
}
|
|
byte[] hashBytes = digest.digest();
|
|
return bytesToHex(hashBytes, true);
|
|
}
|
|
|
|
/**
|
|
* 计算字节数组的 SHA256 哈希值
|
|
*
|
|
* @param data 字节数组
|
|
* @return SHA256 哈希值(小写十六进制字符串)
|
|
*/
|
|
public static String sha256(byte[] data) {
|
|
try {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
byte[] hashBytes = digest.digest(data);
|
|
return bytesToHex(hashBytes);
|
|
} catch (NoSuchAlgorithmException e) {
|
|
throw new RuntimeException("SHA-256 algorithm not found", e);
|
|
}
|
|
}
|
|
|
|
public static String calculateSHA256(File file) throws NoSuchAlgorithmException, IOException {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
try (InputStream inputStream = new FileInputStream(file)) {
|
|
byte[] buffer = new byte[4096];
|
|
int bytesRead;
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
digest.update(buffer, 0, bytesRead);
|
|
}
|
|
}
|
|
byte[] hashBytes = digest.digest();
|
|
return bytesToHex(hashBytes);
|
|
}
|
|
|
|
private static String bytesToHex(byte[] bytes) {
|
|
StringBuilder hexString = new StringBuilder();
|
|
for (byte b : bytes) {
|
|
String hex = String.format("%02x", b & 0xFF);
|
|
/*大写*/
|
|
// String hex = String.format("%02X", b & 0xFF);
|
|
hexString.append(hex);
|
|
}
|
|
return hexString.toString();
|
|
}
|
|
|
|
private static String bytesToHex(byte[] bytes, boolean upcase) {
|
|
String format = upcase ? "%02X" : "%02x";
|
|
StringBuilder hexString = new StringBuilder();
|
|
for (byte b : bytes) {
|
|
String hex = String.format(format, b & 0xFF);
|
|
hexString.append(hex);
|
|
}
|
|
return hexString.toString();
|
|
}
|
|
}
|