using System; using System.Text; using System.IO; using System.Security.Cryptography; namespace MotionFramework.Utility { public static class HashUtility { private static string ToString(byte[] hashBytes) { string result = BitConverter.ToString(hashBytes); result = result.Replace("-", ""); return result.ToLower(); } #region SHA1 [已废弃 - 使用SHA256替代] /// /// 获取字符串的Hash值(已废弃,请使用StringSHA256) /// /// /// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("SHA1算法不安全,请使用StringSHA256方法", false)] public static string StringSHA1(string str) { // 已替换为SHA256实现以提高安全性 return StringSHA256(str); } /// /// 获取文件的Hash值(已废弃,请使用FileSHA256) /// /// /// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("SHA1算法不安全,请使用FileSHA256方法", false)] public static string FileSHA1(string filePath) { // 已替换为SHA256实现以提高安全性 return FileSHA256(filePath); } /// /// 获取数据流的Hash值(已废弃,请使用StreamSHA256) /// /// /// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("SHA1算法不安全,请使用StreamSHA256方法", false)] public static string StreamSHA1(Stream stream) { // 已替换为SHA256实现以提高安全性 return StreamSHA256(stream); } /// /// 获取字节数组的Hash值(已废弃,请使用BytesSHA256) /// /// /// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("SHA1算法不安全,请使用BytesSHA256方法", false)] public static string BytesSHA1(byte[] buffer) { // 已替换为SHA256实现以提高安全性 return BytesSHA256(buffer); } #endregion #region SHA256 [推荐使用] /// /// 获取字符串的SHA256哈希值(推荐使用) /// /// 要计算哈希的字符串 /// SHA256哈希值的十六进制字符串 public static string StringSHA256(string str) { byte[] buffer = Encoding.UTF8.GetBytes(str); return BytesSHA256(buffer); } /// /// 获取文件的SHA256哈希值(推荐使用) /// /// 文件路径 /// SHA256哈希值的十六进制字符串,如果文件不存在或读取失败则返回空字符串 public static string FileSHA256(string filePath) { try { using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { return StreamSHA256(fs); } } catch (FileNotFoundException e) { MotionLog.Exception($"文件不存在: {filePath}\n{e}"); return string.Empty; } catch (DirectoryNotFoundException e) { MotionLog.Exception($"目录不存在: {filePath}\n{e}"); return string.Empty; } catch (UnauthorizedAccessException e) { MotionLog.Exception($"访问被拒绝,权限不足: {filePath}\n{e}"); return string.Empty; } catch (ArgumentException e) { MotionLog.Exception($"参数错误: {filePath}\n{e}"); return string.Empty; } catch (IOException e) { MotionLog.Exception(e.ToString()); return string.Empty; } } /// /// 获取数据流的SHA256哈希值(推荐使用) /// /// 要计算哈希的数据流 /// SHA256哈希值的十六进制字符串 /// /// 使用SHA256算法,生成256位的散列码,提供更高的安全性 /// public static string StreamSHA256(Stream stream) { // 使用SHA256算法替代不安全的SHA1,提供更高的安全性 // 使用 using 语句确保资源正确释放,防止资源泄漏 using (SHA256 hash = SHA256.Create()) { byte[] hashBytes = hash.ComputeHash(stream); return ToString(hashBytes); } } /// /// 获取字节数组的SHA256哈希值(推荐使用) /// /// 要计算哈希的字节数组 /// SHA256哈希值的十六进制字符串 /// /// 使用SHA256算法,生成256位的散列码,提供更高的安全性 /// public static string BytesSHA256(byte[] buffer) { // 使用SHA256算法替代不安全的SHA1,提供更高的安全性 // 使用 using 语句确保资源正确释放,防止资源泄漏 using (SHA256 hash = SHA256.Create()) { byte[] hashBytes = hash.ComputeHash(buffer); return ToString(hashBytes); } } #endregion #region MD5 [已废弃 - 使用SHA256替代] /// /// 获取字符串的MD5(已废弃,请使用StringSHA256) /// /// /// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("MD5算法不安全,请使用StringSHA256方法", false)] public static string StringMD5(string str) { // 已替换为SHA256实现以提高安全性 return StringSHA256(str); } /// /// 获取文件的MD5(已废弃,请使用FileSHA256) /// /// /// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("MD5算法不安全,请使用FileSHA256方法", false)] public static string FileMD5(string filePath) { // 已替换为SHA256实现以提高安全性 return FileSHA256(filePath); } /// /// 获取数据流的MD5(已废弃,请使用StreamSHA256) /// /// /// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("MD5算法不安全,请使用StreamSHA256方法", false)] public static string StreamMD5(Stream stream) { // 已替换为SHA256实现以提高安全性 return StreamSHA256(stream); } /// /// 获取字节数组的MD5(已废弃,请使用BytesSHA256) /// /// /// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。 /// [System.Obsolete("MD5算法不安全,请使用BytesSHA256方法", false)] public static string BytesMD5(byte[] buffer) { // 已替换为SHA256实现以提高安全性 return BytesSHA256(buffer); } #endregion #region CRC32 /// /// 获取字符串的CRC32 /// public static string StringCRC32(string str) { byte[] buffer = Encoding.UTF8.GetBytes(str); return BytesCRC32(buffer); } /// /// 获取文件的CRC32 /// public static string FileCRC32(string filePath) { try { using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { return StreamCRC32(fs); } } catch (FileNotFoundException e) { MotionLog.Exception($"文件不存在: {filePath}\n{e}"); return string.Empty; } catch (DirectoryNotFoundException e) { MotionLog.Exception($"目录不存在: {filePath}\n{e}"); return string.Empty; } catch (UnauthorizedAccessException e) { MotionLog.Exception($"访问被拒绝,权限不足: {filePath}\n{e}"); return string.Empty; } catch (ArgumentException e) { MotionLog.Exception($"参数错误: {filePath}\n{e}"); return string.Empty; } catch (IOException e) { MotionLog.Exception(e.ToString()); return string.Empty; } } /// /// 获取数据流的CRC32 /// public static string StreamCRC32(Stream stream) { // 使用 using 语句确保资源正确释放,防止资源泄漏 using (CRC32Algorithm hash = new CRC32Algorithm()) { byte[] hashBytes = hash.ComputeHash(stream); return ToString(hashBytes); } } /// /// 获取字节数组的CRC32 /// public static string BytesCRC32(byte[] buffer) { // 使用 using 语句确保资源正确释放,防止资源泄漏 using (CRC32Algorithm hash = new CRC32Algorithm()) { byte[] hashBytes = hash.ComputeHash(buffer); return ToString(hashBytes); } } #endregion } }