using System;
using System.ComponentModel;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;
namespace HashDemo
{
public partial class Form1 : Form
{
public enum HashAlgo
{
CRC32,
MD5,
SHA1,
SHA256,
SHA384,
SHA512,
RipeMd,
}
private HashAlgorithm Hash;
private bool hashingFinished;
private FileStream inFile;
private HashAlgo selectedHash;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
BgWorker.ProgressChanged += BgWorker_ProgressChanged;
BgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
FileNameTextBox.DragEnter += FileNameTextBox_DragEnter;
FileNameTextBox.DragDrop += FileNameTextBox_DragDrop;
DragEnter += FileNameTextBox_DragEnter;
DragDrop += FileNameTextBox_DragDrop;
selectedHash = HashAlgo.CRC32;
}
private void BrowseButton_Click(object sender, EventArgs e)
{
DialogResult myDialogResult;
myDialogResult = OpenFile.ShowDialog();
if (myDialogResult == DialogResult.Cancel)
return;
FileNameTextBox.Text = OpenFile.FileName;
}
private void CalculateButton_Click(object sender, EventArgs e)
{
BgWorker.RunWorkerAsync();
CalculateButton.Enabled = false;
}
private void CrcRadio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.CRC32;
}
private void Md5Radio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.MD5;
}
private void Sha1Radio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.SHA1;
}
private void Sha256Radio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.SHA256;
}
private void Sha384Radio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.SHA384;
}
private void Sha512Radio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.SHA512;
}
private void RipemdRadio_CheckedChanged(object sender, EventArgs e)
{
selectedHash = HashAlgo.RipeMd;
}
private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressBar.Value = e.ProgressPercentage;
}
private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
{
switch (selectedHash)
{
case HashAlgo.MD5:
Hash = new MD5CryptoServiceProvider();
break;
case HashAlgo.SHA1:
Hash = new SHA1CryptoServiceProvider();
break;
case HashAlgo.SHA256:
Hash = new SHA256CryptoServiceProvider();
break;
case HashAlgo.SHA384:
Hash = new SHA384CryptoServiceProvider();
break;
case HashAlgo.SHA512:
Hash = new SHA512CryptoServiceProvider();
break;
case HashAlgo.RipeMd:
Hash = new RIPEMD160Managed();
break;
case HashAlgo.CRC32:
Hash = new CRC32();
break;
}
try
{
inFile = new FileStream(FileNameTextBox.Text, FileMode.Open);
const int bufSize = 4096;
var buffer = new byte[bufSize];
int readBytes = 1;
long filePos;
long fileLength = inFile.Length;
while (readBytes > 0)
{
int progress;
readBytes = inFile.Read(buffer, 0, bufSize);
filePos = inFile.Position;
if (readBytes == 4096)
{
Hash.TransformBlock(buffer, 0, bufSize, null, 0);
progress = (int) ((filePos/(float) fileLength)*100);
}
else
{
Hash.TransformFinalBlock(buffer, 0, readBytes);
progress = 100;
}
BgWorker.ReportProgress(progress);
}
hashingFinished = true;
inFile.Close();
}
catch (IOException)
{
MessageBox.Show("无法打开所选文件.", "文件打开错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (CryptographicException)
{
MessageBox.Show("处理文件时出错.", "哈希错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (hashingFinished)
hashTextBox.Text = BitConverter.ToString(Hash.Hash).Replace("-", "").ToLower();
CalculateButton.Enabled = true;
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
var form = new About();
form.ShowDialog();
}
private void FileNameTextBox_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.All;
}
private void FileNameTextBox_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var myFiles = (string[]) e.Data.GetData(DataFormats.FileDrop);
FileNameTextBox.Text = myFiles[0];
}
}
}
}
CRC32.cs代码:
using System;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace HashDemo
{
public class CRC32 : HashAlgorithm
{
#region 构造函数
static CRC32()
{
_crc32TablesCache = Hashtable.Synchronized(new Hashtable());
_defaultCRC = new CRC32();
}
public CRC32()
: this(DefaultPolynomial)
{
}
[CLSCompliant(false)]
public CRC32(uint polynomial)
{
HashSizeValue = 32;
_crc32Table = (uint[]) _crc32TablesCache[polynomial];
if (_crc32Table == null)
{
_crc32Table = _buildCRC32Table(polynomial);
_crc32TablesCache.Add(polynomial, _crc32Table);
}
Initialize();
}
#endregion
#region 属性
[CLSCompliant(false)] public static readonly uint DefaultPolynomial = 0xEDB88320;
#endregion
#region 方法
public override void Initialize()
{
_crc = _allOnes;
}
protected override void HashCore(byte[] buffer, int offset, int count)
{
for (int i = offset; i < count; i++)
{
ulong ptr = (_crc & 0xFF) ^ buffer[i];
_crc >>= 8;
_crc ^= _crc32Table[ptr];
}
}
protected override byte[] HashFinal()
{
var finalHash = new byte[4];
ulong finalCRC = _crc ^ _allOnes;
finalHash[0] = (byte) ((finalCRC >> 0) & 0xFF);
finalHash[1] = (byte) ((finalCRC >> 8) & 0xFF);
finalHash[2] = (byte) ((finalCRC >> 16) & 0xFF);
finalHash[3] = (byte) ((finalCRC >> 24) & 0xFF);
Array.Reverse(finalHash);
return finalHash;
}
public static int Compute(string asciiString)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(asciiString));
}
public static int Compute(Stream inputStream)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(inputStream));
}
public static int Compute(byte[] buffer)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(buffer));
}
public static int Compute(byte[] buffer, int offset, int count)
{
_defaultCRC.Initialize();
return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count));
}
public byte[] ComputeHash(string asciiString)
{
byte[] rawBytes = Encoding.ASCII.GetBytes(asciiString);
return ComputeHash(rawBytes);
}
public new byte[] ComputeHash(Stream inputStream)
{
var buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, 4096)) > 0)
{
HashCore(buffer, 0, bytesRead);
}
return HashFinal();
}
public new byte[] ComputeHash(byte[] buffer)
{
return ComputeHash(buffer, 0, buffer.Length);
}
public new byte[] ComputeHash(byte[] buffer, int offset, int count)
{
HashCore(buffer, offset, count);
return HashFinal();
}
#endregion
#region 私有部分
private static uint _allOnes = 0xffffffff;
private static readonly CRC32 _defaultCRC;
private static readonly Hashtable _crc32TablesCache;
private readonly uint[] _crc32Table;
private uint _crc;
private static uint[] _buildCRC32Table(uint polynomial)
{
uint crc;
var table = new uint[256];
for (int i = 0; i < 256; i++)
{
crc = (uint) i;
for (int j = 8; j > 0; j--)
{
if ((crc & 1) == 1)
crc = (crc >> 1) ^ polynomial;
else
crc >>= 1;
}
table[i] = crc;
}
return table;
}
private static int ToInt32(byte[] buffer)
{
return BitConverter.ToInt32(buffer, 0);
}
#endregion
}
}
设计界面如图:

运行结果如图:
