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
}
}
设计界面如图:
运行结果如图: