原理:
MD5文件打开关闭没事,改变内容MD5码就会改变,是对内容进行加密后的结果。
MD5 (tanajiya.tar.gz) = 38b8c2c1093dd0fec383a9d9ac940515,这就是tanajiya.tar.gz文件的数字签名。MD5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的MD5信息摘要。
大家都知道,地球上任何人都有自己独一无二的指纹,这常常成为司法机关鉴别罪犯身份最值得信赖的方法;与之类似,MD5就可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的“数字指纹”,如果任何人对文件做了任何改动,其MD5值也就是对应的“数字指纹”都会发生变化。
生成字符串的MD5码:
/// <summary>
/// 生成字符串的MD5码
/// </summary>
/// <param name="sInput"></param>
/// <returns></returns>
public static string GetMd5FromString(string sInput)
{
var lstData = Encoding.GetEncoding("utf-8").GetBytes(sInput);
var lstHash = new MD5CryptoServiceProvider().ComputeHash(lstData);
var result = new StringBuilder(32);
for (int i = 0; i < lstHash.Length; i++)
{
result.Append(lstHash[i].ToString("x2").ToUpper());
}
return result.ToString();
}
生成文件的MD5码:
以文件形式复制mdb文件不会改变MD5码,但在ArcMAP中复制会改变MD5码;程序中打开遍历不会改变MD5码,但是编辑后会改变;用Office操作mdb后就会该改变MD5码,因为Office会时时保存
/// <summary>
/// 获取文件的MD5码
/// </summary>
/// <param name="fileName">文件路径</param>
/// <returns></returns>
public static string GetMD5HashFromFile(string fileName)
{
using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(file);
StringBuilder result = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
result.Append(hash[i].ToString("x2"));
}
//或则使用
//string sMd5 = BitConverter.ToString(hash).Replace("-", "").ToUpper();
return result.ToString();
}
}
生成GDB的MD5码:
以文件形式复制gdb文件不会改变MD5码,但在ArcMap中复制gdb会改变。编辑修改内容后会改变MD5码
/// <summary>
/// 生成FileGDB的MD5码
/// </summary>
/// <param name="sFgdbPath"></param>
/// <returns></returns>
public static string GetMd5FromFgdb(string sFgdbPath)
{
var sMd5 = string.Empty;
try
{
var files = Directory.GetFiles(sFgdbPath, "*.gdbtable", SearchOption.AllDirectories).ToList();
files.Sort();
List<string> lstResult = new List<string>();
files.ForEach(p => lstResult.Add(GetMD5HashFromFile(p)));
sMd5 = GetMd5FromString(string.Join(",", lstResult));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return sMd5;
}
使用压缩压缩流:
/// <summary>
/// 获取GDB文件的MD5码
/// </summary>
/// <param name="path">文件夹路径</param>
/// <returns></returns>
public static string CreateMd5ForGDB(string path)
{
var files = Directory.GetFiles(path, "*.gdbtable", SearchOption.AllDirectories).ToList();
files.Sort();
var md5s = "";
foreach (var file in files)
{
md5s = md5s + GetMD5HashFromFile(file);
}
byte[] rawData = System.Text.Encoding.UTF8.GetBytes(md5s);
byte[] zippedData = Compress(rawData);
return (string)(Convert.ToBase64String(zippedData));
}
/// <summary>
/// GZip压缩
/// </summary>
/// <param name="rawData"></param>
/// <returns></returns>
public static byte[] Compress(byte[] rawData)
{
MemoryStream ms = new MemoryStream();
GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true);
compressedzipStream.Write(rawData, 0, rawData.Length);
compressedzipStream.Close();
return ms.ToArray();
}
生成文件夹的MD5码:
/// <summary>
/// 获取文件夹的MD5码
/// </summary>
/// <param name="path">文件夹路径</param>
/// <returns></returns>
public static string CreateMd5ForFolder(string path)
{
// assuming you want to include nested folders
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
.OrderBy(p => p).ToList();
MD5 md5 = MD5.Create();
for (int i = 0; i < files.Count; i++)
{
string file = files[i];
// hash path
string relativePath = file.Substring(path.Length + 1);
byte[] pathBytes = Encoding.UTF8.GetBytes(relativePath.ToLower());
md5.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
// hash contents
byte[] contentBytes = File.ReadAllBytes(file);
if (i == files.Count - 1)
md5.TransformFinalBlock(contentBytes, 0, contentBytes.Length);
else
md5.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0);
}
return BitConverter.ToString(md5.Hash).Replace("-", "").ToLower();
}