方式一:
双击运行,输入字符串计算MD5值;或拖动任意文件或文件夹到到工具上,自动计算MD5值。
方式二:
拖拽文件或文件夹至getMD5.exe上,可自动计算文件或文件夹下所有文件的MD5值,保存至文件MD5.txt中
方式三:
通过cmd命令调用(类似方式二)
REM 获取1.txt和files目录下所有文件的MD5值
getMD5.exe "D:\tmp\1.txt;C:\Users\Administrator\Desktop\files"
工具源码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace getMD5
{
//示例:
// MD5.Encrypt("a"); // 计算字符串MD5值
// MD5.Encrypt(new FileInfo("D:\\1.rar")); // 计算文件MD5值
// MD5.Encrypt(byte[] Bytes); // 计算Byte数组MD5值
//MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
//MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
//MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
//MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
//MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
class MD5
{
#region MD5调用接口
/// <summary>
/// 计算data的MD5值
/// </summary>
public static string Encrypt(string data)
{
uint[] X = To16Array(data);
return calculate(X);
}
/// <summary>
/// 计算byte数组的MD5值
/// </summary>
public static string Encrypt(byte[] Bytes)
{
uint[] X = To16Array(Bytes);
return calculate(X);
}
/// <summary>
/// 计算文件的MD5值
/// </summary>
public static string Encrypt(FileInfo file)
{
uint[] X = To16Array(file);
return calculate(X);
}
#endregion
#region MD5计算逻辑
/// <summary>
/// 转化byte数组为uint数组,数组长度为16的倍数
///
/// 1、字符串转化为字节数组,每4个字节转化为一个uint,依次存储到uint数组
/// 2、附加0x80作为最后一个字节
/// 3、在uint数组最后位置记录文件字节长度信息
/// </summary>
public static uint[] To16Array(byte[] Bytes)
{
uint DataLen = (uint)Bytes.Length;
// 计算FileLen对应的uint长度(要求为16的倍数、预留2个uint、最小为16)
uint ArrayLen = (((DataLen + 8) / 64) + 1) * 16;
uint[] Array = new uint[ArrayLen];
uint ArrayPos = 0;
int pos = 0;
uint ByteCount = 0;
for (ByteCount = 0; ByteCount < DataLen; ByteCount++)
{
// 每4个Byte转化为1个uint
ArrayPos = ByteCount / 4;
pos = (int)(ByteCount % 4) * 8;
Array[ArrayPos] = Array[ArrayPos] | ((uint)Bytes[ByteCount] << pos);
}
// 附加0x80作为最后一个字节,添加到uint数组对应位置
ArrayPos = ByteCount / 4;
pos = (int)(ByteCount % 4) * 8;
Array[ArrayPos] = Array[ArrayPos] | ((uint)0x80 << pos);
// 记录总长度信息
Array[ArrayLen - 2] = (DataLen << 3);
Array[ArrayLen - 1] = (DataLen >> 29);
return Array;
}
/// <summary>
/// 转化字符串为uint数组,数组长度为16的倍数
///
/// 1、字符串转化为字节数组,每4个字节转化为一个uint,依次存储到uint数组
/// 2、附加0x80作为最后一个字节
/// 3、在uint数组最后位置记录文件字节长度信息
/// </summary>
public static uint[] To16Array(string data)
{
byte[] datas = System.Text.Encoding.Default.GetBytes(data);
return To16Array(datas);
}
/// <summary>
/// 转化文件为uint数组,数组长度为16的倍数
///
/// 1、读取文件字节信息,每4个字节转化为一个uint,依次存储到uint数组
/// 2、附加0x80作为最后一个字节
/// 3、在uint数组最后位置记录文件字节长度信息
/// </summary>
public static uint[] To16Array(FileInfo info)
{
FileStream fs = new FileStream(info.FullName, FileMode.Open);// 读取方式打开,得到流
int SIZE = 1024 * 1024 * 10; // 10M缓存
byte[] datas = new byte[SIZE]; // 要读取的内容会放到这个数组里
int countI = 0;
long offset = 0;
// 计算FileLen对应的uint长度(要求为16的倍数、预留2个uint、最小为16)
uint FileLen = (uint)info.Length;
uint ArrayLen = (((FileLen + 8) / 64) + 1) * 16;
uint[] Array = new uint[ArrayLen];
int pos = 0;
uint ByteCount = 0;
uint ArrayPos = 0;
while (ByteCount < FileLen)
{
if (countI == 0)
{
fs.Seek(offset, SeekOrigin.Begin);// 定位到指定字节
fs.Read(datas, 0, datas.Length);
offset += SIZE;
}
// 每4个Byte转化为1个uint
ArrayPos = ByteCount / 4;
pos = (int)(ByteCount % 4) * 8;
Array[ArrayPos] = Array[ArrayPos] | ((uint)datas[countI] << pos);
ByteCount = ByteCount + 1;
countI++;
if (countI == SIZE) countI = 0;
}
// 附加0x80作为最后一个字节,添加到uint数组对应位置
ArrayPos = ByteCount / 4;
pos = (int)(ByteCount % 4) * 8;
Array[ArrayPos] = Array[ArrayPos] | ((uint)0x80 << pos);
// 记录总长度信息
Array[ArrayLen - 2] = (FileLen<< 3);
Array[ArrayLen - 1] = (FileLen>>29);
fs.Close();
return Array;
}
private static uint F(uint x, uint y, uint z)
{
return (x & y) | ((~x) & z);
}
private static uint G(uint x, uint y, uint z)
{
return (x & z) | (y & (~z));
}
// 0^0^0 = 0
// 0^0^1 = 1
// 0^1^0 = 1
// 0^1^1 = 0
// 1^0^0 = 1
// 1^0^1 = 0
// 1^1^0 = 0
// 1^1^1 = 1
private static uint H(uint x, uint y, uint z)
{
return (x ^ y ^ z);
}
private static uint I(uint x, uint y, uint z)
{
return (y ^ (x | (~z)));
}
// 循环左移
private static uint RL(uint x, int y)
{
y = y % 32;
return (x << y) | (x >> (32 - y));
}
private static void md5_FF(ref uint a, uint b, uint c, uint d, uint x, int s, uint ac)
{
uint f = F(b, c, d);
a = x + ac + a + f;
a = RL(a, s);
a = a + b;
}
private static void md5_GG(ref uint a, uint b, uint c, uint d, uint x, int s, uint ac)
{
uint g = G(b, c, d);
a = x + ac + a + g;
a = RL(a, s);
a = a + b;
}
private static void md5_HH(ref uint a, uint b, uint c, uint d, uint x, int s, uint ac)
{
uint h = H(b, c, d);
a = x + ac + a + h;
a = RL(a, s);
a = a + b;
}
private static void md5_II(ref uint a, uint b, uint c, uint d, uint x, int s, uint ac)
{
uint i = I(b, c, d);
a = x + ac + a + i;
a = RL(a, s);
a = a + b;
}
private static string RHex(uint n)
{
string S = Convert.ToString(n, 16);
return ReOrder(S);
}
// 16进制串重排序 67452301 -> 01234567
private static string ReOrder(String S)
{
string T = "";
for (int i = S.Length - 2; i >= -1; i = i - 2)
{
if (i == -1) T = T + "0" + S[i + 1];
else T = T + "" + S[i] + S[i + 1];
}
return T;
}
/// <summary>
/// 对长度为16倍数的uint数组,执行md5数据摘要,输出md5信息
/// </summary>
public static string calculate(uint[] x)
{
//uint time1 = DateTime.Now.Ticks;
// 7 12 17 22
// 5 9 14 20
// 4 11 16 23
// 6 10 15 21
const int S11 = 7;
const int S12 = 12;
const int S13 = 17;
const int S14 = 22;
const int S21 = 5;
const int S22 = 9;
const int S23 = 14;
const int S24 = 20;
const int S31 = 4;
const int S32 = 11;
const int S33 = 16;
const int S34 = 23;
const int S41 = 6;
const int S42 = 10;
const int S43 = 15;
const int S44 = 21;
uint a = 0x67452301;
uint b = 0xEFCDAB89;
uint c = 0x98BADCFE;
uint d = 0x10325476;
for (int k = 0; k < x.Length; k += 16)
{
uint AA = a;
uint BB = b;
uint CC = c;
uint DD = d;
md5_FF(ref a, b, c, d, x[k + 0], S11, 0xD76AA478); // 3604027302
md5_FF(ref d, a, b, c, x[k + 1], S12, 0xE8C7B756); // 877880356
md5_FF(ref c, d, a, b, x[k + 2], S13, 0x242070DB); // 2562383102
md5_FF(ref b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
md5_FF(ref a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
md5_FF(ref d, a, b, c, x[k + 5], S12, 0x4787C62A);
md5_FF(ref c, d, a, b, x[k + 6], S13, 0xA8304613);
md5_FF(ref b, c, d, a, x[k + 7], S14, 0xFD469501);
md5_FF(ref a, b, c, d, x[k + 8], S11, 0x698098D8);
md5_FF(ref d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
md5_FF(ref c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
md5_FF(ref b, c, d, a, x[k + 11], S14, 0x895CD7BE);
md5_FF(ref a, b, c, d, x[k + 12], S11, 0x6B901122);
md5_FF(ref d, a, b, c, x[k + 13], S12, 0xFD987193);
md5_FF(ref c, d, a, b, x[k + 14], S13, 0xA679438E);
md5_FF(ref b, c, d, a, x[k + 15], S14, 0x49B40821); //3526238649
md5_GG(ref a, b, c, d, x[k + 1], S21, 0xF61E2562);
md5_GG(ref d, a, b, c, x[k + 6], S22, 0xC040B340); //1572812400
md5_GG(ref c, d, a, b, x[k + 11], S23, 0x265E5A51);
md5_GG(ref b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
md5_GG(ref a, b, c, d, x[k + 5], S21, 0xD62F105D);
md5_GG(ref d, a, b, c, x[k + 10], S22, 0x2441453);
md5_GG(ref c, d, a, b, x[k + 15], S23, 0xD8A1E681);
md5_GG(ref b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
md5_GG(ref a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
md5_GG(ref d, a, b, c, x[k + 14], S22, 0xC33707D6);
md5_GG(ref c, d, a, b, x[k + 3], S23, 0xF4D50D87);
md5_GG(ref b, c, d, a, x[k + 8], S24, 0x455A14ED);
md5_GG(ref a, b, c, d, x[k + 13], S21, 0xA9E3E905);
md5_GG(ref d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
md5_GG(ref c, d, a, b, x[k + 7], S23, 0x676F02D9);
md5_GG(ref b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
md5_HH(ref a, b, c, d, x[k + 5], S31, 0xFFFA3942); // 3750198684 2314002400 1089690627 990001115 0 4 -> 2749600077
md5_HH(ref d, a, b, c, x[k + 8], S32, 0x8771F681); // 990001115
md5_HH(ref c, d, a, b, x[k + 11], S33, 0x6D9D6122); // 1089690627
md5_HH(ref b, c, d, a, x[k + 14], S34, 0xFDE5380C); // 2314002400
md5_HH(ref a, b, c, d, x[k + 1], S31, 0xA4BEEA44); // 555633090
md5_HH(ref d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
md5_HH(ref c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
md5_HH(ref b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
md5_HH(ref a, b, c, d, x[k + 13], S31, 0x289B7EC6);
md5_HH(ref d, a, b, c, x[k + 0], S32, 0xEAA127FA);
md5_HH(ref c, d, a, b, x[k + 3], S33, 0xD4EF3085);
md5_HH(ref b, c, d, a, x[k + 6], S34, 0x4881D05);
md5_HH(ref a, b, c, d, x[k + 9], S31, 0xD9D4D039);
md5_HH(ref d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
md5_HH(ref c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
md5_HH(ref b, c, d, a, x[k + 2], S34, 0xC4AC5665); // 1444303940
md5_II(ref a, b, c, d, x[k + 0], S41, 0xF4292244); // 808311156
md5_II(ref d, a, b, c, x[k + 7], S42, 0x432AFF97);
md5_II(ref c, d, a, b, x[k + 14], S43, 0xAB9423A7);
md5_II(ref b, c, d, a, x[k + 5], S44, 0xFC93A039);
md5_II(ref a, b, c, d, x[k + 12], S41, 0x655B59C3);
md5_II(ref d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
md5_II(ref c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
md5_II(ref b, c, d, a, x[k + 1], S44, 0x85845DD1);
md5_II(ref a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
md5_II(ref d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
md5_II(ref c, d, a, b, x[k + 6], S43, 0xA3014314);
md5_II(ref b, c, d, a, x[k + 13], S44, 0x4E0811A1);
md5_II(ref a, b, c, d, x[k + 4], S41, 0xF7537E82);
md5_II(ref d, a, b, c, x[k + 11], S42, 0xBD3AF235);
md5_II(ref c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
md5_II(ref b, c, d, a, x[k + 9], S44, 0xEB86D391); // 4120542881
a = a + AA; //3844921825
b = b + BB;
c = c + CC;
d = d + DD;
}
string MD5 = RHex(a) + RHex(b) + RHex(c) + RHex(d);
//uint time2 = DateTime.Now.Ticks;
//MessageBox.Show("MD5计算耗时:" + ((time2 - time1) / 10000000f) + "秒");
return MD5;
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace getMD5
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (args.Length == 0) Application.Run(new Form_MD5());
else if (args.Length == 1)
{
string[] files = args[0].Split(';');
string filesNames = Form_MD5.toSubDirFileNames(files);
files = filesNames.Split(';');
string tmp = Form_MD5.getFilesMD5(files); // 计算文件MD5值
Form_MD5.SaveProcess(tmp);
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace getMD5
{
public partial class Form_MD5 : Form
{
public Form_MD5()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = MD5.Encrypt(textBox1.Text, 32);
}
private void Form_DragEnter(object sender, DragEventArgs e)
{
dragEnter(e);
}
private void Form_DragDrop(object sender, DragEventArgs e)
{
TextBox textBox = sender as TextBox;
textBox.Text = dragDrop(e); // 获取拖入的文件
string[] files = textBox.Text.Split(';');
string tmp = getFilesMD5(files); // 计算文件MD5值
textBox1.Text = tmp;
SaveProcess(tmp, "MD5.txt");
}
// 计算各文件对应的MD5值
public static String getFilesMD5(string[] files)
{
string tmp = "";
foreach (string file in files)
{
if (System.IO.File.Exists(file))
{
string data = fileToString(file);
string md5 = MD5.Encrypt(data, 32);
tmp += "\r\n" + file + "(" + md5 + ")";
}
}
return tmp;
}
#region 文件读取与保存
/// <summary>
/// 获取文件中的数据串
/// </summary>
public static string fileToString(String filePath)
{
string str = "";
//获取文件内容
if (System.IO.File.Exists(filePath))
{
System.IO.StreamReader file1 = new System.IO.StreamReader(filePath, Encoding.Default);//读取文件中的数据
str = file1.ReadToEnd(); //读取文件中的全部数据
file1.Close();
file1.Dispose();
}
return str;
}
/// <summary>
/// 保存数据data到文件处理过程,返回值为保存的文件名
/// </summary>
public static String SaveProcess(String data, String name = "", String CurDir = "")
{
if (CurDir.Equals("")) CurDir = System.AppDomain.CurrentDomain.BaseDirectory; //设置当前目录
if (name.Equals("")) name = "MD5.txt";
if (!System.IO.Directory.Exists(CurDir)) System.IO.Directory.CreateDirectory(CurDir); //该路径不存在时,在当前文件目录下创建文件夹"导出.."
//不存在该文件时先创建
String filePath = CurDir + name;
System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false); //文件已覆盖方式添加内容
file1.Write(data); //保存数据到文件
file1.Close(); //关闭文件
file1.Dispose(); //释放对象
return filePath;
}
#endregion
# region 文件拖拽
/// <summary>
/// 文件拖进事件处理:
/// </summary>
public void dragEnter(DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop)) //判断拖来的是否是文件
e.Effect = DragDropEffects.Link; //是则将拖动源中的数据连接到控件
else e.Effect = DragDropEffects.None;
}
/// <summary>
/// 文件放下事件处理:
/// 放下, 另外需设置对应控件的 AllowDrop = true;
/// 获取的文件名形如 "d:\1.txt;d:\2.txt"
/// </summary>
public string dragDrop(DragEventArgs e)
{
Array file = (System.Array)e.Data.GetData(DataFormats.FileDrop);//将拖来的数据转化为数组存储
return toSubDirFileNames(file);
}
// 获取所有files目录下的所有文件,转化为单个串
public static string toSubDirFileNames(Array files)
{
StringBuilder filesName = new StringBuilder("");
foreach (object I in files)
{
string str = I.ToString();
System.IO.FileInfo info = new System.IO.FileInfo(str);
//若为目录,则获取目录下所有子文件名
if ((info.Attributes & System.IO.FileAttributes.Directory) != 0)
{
str = getAllFiles(str);
if (!str.Equals("")) filesName.Append((filesName.Length == 0 ? "" : ";") + str);
}
//若为文件,则获取文件名
else if (System.IO.File.Exists(str))
filesName.Append((filesName.Length == 0 ? "" : ";") + str);
}
return filesName.ToString();
}
/// <summary>
/// 判断path是否为目录
/// </summary>
public bool IsDirectory(String path)
{
System.IO.FileInfo info = new System.IO.FileInfo(path);
return (info.Attributes & System.IO.FileAttributes.Directory) != 0;
}
/// <summary>
/// 获取目录path下所有子文件名
/// </summary>
public static string getAllFiles(String path)
{
StringBuilder str = new StringBuilder("");
if (System.IO.Directory.Exists(path))
{
//所有子文件名
string[] files = System.IO.Directory.GetFiles(path);
foreach (string file in files)
str.Append((str.Length == 0 ? "" : ";") + file);
//所有子目录名
string[] Dirs = System.IO.Directory.GetDirectories(path);
foreach (string dir in Dirs)
{
string tmp = getAllFiles(dir); //子目录下所有子文件名
if (!tmp.Equals("")) str.Append((str.Length == 0 ? "" : ";") + tmp);
}
}
return str.ToString();
}
# endregion
}
}
namespace getMD5
{
partial class Form_MD5
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.SuspendLayout();
//
// button1
//
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.button1.Location = new System.Drawing.Point(182, 308);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "计算MD5";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.AllowDrop = true;
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Margin = new System.Windows.Forms.Padding(0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(257, 305);
this.textBox1.TabIndex = 1;
this.toolTip1.SetToolTip(this.textBox1, "可拖动文件至此,查看文件的MD5值");
this.textBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form_DragDrop);
this.textBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form_DragEnter);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(257, 335);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "MD5";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.ToolTip toolTip1;
}
}