I am Green Lantern!
| Hot-headed. You have strong will power and a good imagination. ![]() |
Labels: Misc
More Hash - Part IITaking the same approach and design as Part I of this 'post' here is the resulting code for 'hashing' Delphi style. Again, this uses the System.Security.Cryptography Namespace to compute the hash values. This application used the MD5, SHA1,SHA2566, SHA384 and SHA512 classes. I did change the visibility of some of the functions as compared to the 'other' version.
uses System.IO, System.Security.Cryptography, System.Text;
type
hashtype = (MD5,SHA1,SHA256,SHA384,SHA512);
frmMain = class(System.Windows.Forms.Form)
procedure GroupCompare_CheckedChanged(sender: System.Object; e: System.EventArgs);
procedure btnFile_Click(sender: System.Object; e: System.EventArgs);
procedure btnCompare_Click(sender: System.Object; e: System.EventArgs);
private
procedure ClearForm;
function GetHash(contents: array of byte; hasht: hashtype): string;
function GetByteString(data: array of Byte): string;
public
function GetFileHash(const filename: string; hasht: hashtype): string;
function GetStringHash(const input: string; hasht: hashtype): string;
end;
procedure frmMain.ClearForm;
begin
txtValue1.Text := '';
txtValue2.Text := '';
txtResults1.Text := '';
txtResults2.Text := '';
end;
procedure frmMain.btnFile_Click(sender: System.Object; e: System.EventArgs);
begin
if ofdFiles.ShowDialog = System.Windows.Forms.DialogResult.OK then
begin
case Convert.ToInt32(Button(sender).Tag.ToString) of
0: txtValue1.Text:= ofdFiles.FileName;
1: txtValue2.Text:= ofdFiles.FileName;
end;
end;
end;
function frmMain.GetByteString(data: array of Byte): string;
var
sBuilder: StringBuilder;
i: integer;
begin
sBuilder:= StringBuilder.Create();
for i:= 0 to Length(data) - 1 do
begin
sBuilder.Append(data[i].ToString('x2'));
end;
result:= sBuilder.ToString();
end;
function frmMain.GetFileHash(const filename: string; hasht: hashtype): string;
var
oFileStream: System.IO.FileStream;
instance: FileInfo;
lBytes: System.Int64;
filecontents: array of byte;
begin
try
if (filename <> '') then
begin
instance:= FileInfo.Create(filename);
oFileStream:= instance.OpenRead;
lBytes:= oFileStream.Length;
SetLength(filecontents, lBytes);
oFileStream.Read(filecontents, 0, lBytes);
oFileStream.Close();
result:= GetHash(filecontents, hasht);
end
else
begin
result:= '';
end;
except on ex: Exception do
begin
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
result:= '';
end;
end;
end;
function frmMain.GetHash(contents: array of byte; hasht: hashtype): string;
var
res: array of Byte;
HashA: HashAlgorithm;
begin
Case hasht of
hashtype.MD5: begin
HashA:= MD5CryptoServiceProvider.Create;
res:= HashA.ComputeHash(contents)
end;
hashtype.SHA1: begin
HashA:= SHA1Managed.Create;
res:= HashA.ComputeHash(contents);
end;
hashtype.SHA256: begin
HashA:= SHA256Managed.Create;
res:= HashA.ComputeHash(contents);
end;
hashtype.SHA384: begin
HashA:= SHA384Managed.Create;
res:= HashA.ComputeHash(contents);
end;
hashtype.SHA512: begin
HashA:= SHA512Managed.Create;
res:= HashA.ComputeHash(contents);
end;
end;
result:= GetByteString(res);
end;
function frmMain.GetStringHash(const input: string; hasht: hashtype): string;
begin
result:= GetHash(Encoding.Default.GetBytes(input), hasht);
end;
procedure frmMain.btnCompare_Click(sender: System.Object; e: System.EventArgs);
var
myCursor: System.Windows.Forms.Cursor;
hasht: hashtype;
begin
myCursor:= Cursor;
Cursor:= Cursors.WaitCursor;
try
try
if radMD5.Checked then
hasht:= hashtype.MD5;
if radSHA1.Checked then
hasht:= hashtype.SHA1;
if radSHA256.Checked then
hasht:= hashtype.SHA256;
if radSHA384.Checked then
hasht:= hashtype.SHA384;
if radSHA512.Checked then
hasht:= hashtype.SHA512;
if radFiles.Checked then
begin
txtResults1.Text:= GetFileHash(txtValue1.Text, hasht);
txtResults2.Text:= GetFileHash(txtValue2.Text, hasht);
end
else
begin
txtResults1.Text:= GetStringHash(txtValue1.Text, hasht);
txtResults2.Text:= GetStringHash(txtValue2.Text, hasht);
end;
if (System.&String.Compare(txtResults1.Text, txtResults2.Text) = 0) then
begin
picResult.Image:= ImageList1.Images[1];
end
else
begin
picResult.Image:= ImageList1.Images[0];
end;
except
on ex: Exception do
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
end;
finally
Cursor:= myCursor;
end;
end;
procedure frmMain.GroupCompare_CheckedChanged(sender: System.Object; e: System.EventArgs);
var
i: System.Int32;
begin
ClearForm;
if sender is control then
begin
try
i:= Convert.ToInt32(Control(Sender).Tag.ToString);
except
i:= 0;
end;
end;
case i of
0: begin
lblValue1.Text:= 'File 1:';
lblValue2.Text:= 'File 2:';
txtValue1.ReadOnly:= True;
txtValue2.ReadOnly:= True;
btnValue1.Visible:= True;
btnValue2.Visible:= True;
end;
1: begin
lblValue1.Text:= 'String 1:';
lblValue2.Text:= 'String 2:';
txtValue1.ReadOnly:= False;
txtValue2.ReadOnly:= False;
btnValue1.Visible:= False;
btnValue2.Visible:= False;
end;
end;
end;
More Hash - Part IYesterday I discussed using the System.Security.Cryptography Namespace to compute the hash value of files. Hash values of files can be used to quickly compare two files to see if they are identical. Due to the irreversible nature of Hash values, they are useful in password situations. For example, if you have an application that requires authentication you can compute the hash of a user's password and store that information. When it comes time to authenticate the user you can compare the hash value of the entered password with the stored hash value. This eliminates the storage of the actual password value, which could lead to well, problems. I had put together an application that compares the hash values of two files or strings to determine if the data is identical. This application can also be used to generate hash values. This application used the MD5, SHA1, SHA256, SHA384 and SHA512 classes. The hash values are displayed in Hexadecimal notation. If you're interested in just the application it can be downloaded here. Here is the VB.NET source. I will post the Delphi source later.
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text
Public Class frmMain
Enum HashType
MD5
SHA1
SHA256
SHA384
SHA512
End Enum
Private Sub GroupCompare_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles radFiles.CheckedChanged, radStrings.CheckedChanged
ClearForm()
Select Case CType(sender, Control).Tag
Case "Files"
lblValue1.Text = "File 1:"
lblValue2.Text = "File 2:"
txtValue1.ReadOnly = True
txtValue2.ReadOnly = True
btnValue1.Visible = True
btnValue2.Visible = True
Case "Strings"
lblValue1.Text = "String 1:"
lblValue2.Text = "String 2:"
txtValue1.ReadOnly = False
txtValue2.ReadOnly = False
btnValue1.Visible = False
btnValue2.Visible = False
End Select
End Sub
Private Sub txt_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles txtValue1.TextChanged, txtValue2.TextChanged, _
txtResults1.TextChanged, txtResults2.TextChanged
ToolTip1.SetToolTip(CType(sender, Control), CType(sender, Control).Text)
End Sub
Private Sub btnFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnValue1.Click, btnValue2.Click
If ofdFiles.ShowDialog Then
Select Case CType(sender, Button).Tag
Case 0
txtValue1.Text = ofdFiles.FileName
Case 1
txtValue2.Text = ofdFiles.FileName
End Select
End If
End Sub
Private Sub ClearForm()
txtValue1.Text = ""
txtValue2.Text = ""
txtResults1.Text = ""
txtResults2.Text = ""
End Sub
Private Sub btnCompare_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCompare.Click
Dim myCursor As Cursor
Dim hasht As hashtype
myCursor = Cursor
Cursor = Cursors.WaitCursor
Try
If radMD5.Checked Then
hasht = hashtype.MD5
End If
If radSHA1.Checked Then
hasht = hashtype.SHA1
End If
If radSHA256.Checked Then
hasht = hashtype.SHA256
End If
If radSHA384.Checked Then
hasht = hashtype.SHA384
End If
If radSHA512.Checked Then
hasht = hashtype.SHA512
End If
If radFiles.Checked Then
txtResults1.Text = GetFileHash(txtValue1.Text, hasht)
txtResults2.Text = GetFileHash(txtValue2.Text, hasht)
ElseIf radStrings.Checked Then
txtResults1.Text = GetStringHash(txtValue1.Text, hasht)
txtResults2.Text = GetStringHash(txtValue2.Text, hasht)
End If
If (String.Compare(txtResults1.Text, txtResults2.Text) = 0) Then
picResult.Image = ImageList1.Images(1)
Else
picResult.Image = ImageList1.Images(0)
End If
Catch ex As Exception
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
Cursor = myCursor
End Try
End Sub
Private Function GetFileHash(ByVal filename As String, ByVal hasht As hashtype) As String
Dim oFileStream As System.IO.FileStream
Dim lBytes As Long
Try
If filename <> "" Then
Dim instance As New FileInfo(filename)
oFileStream = instance.OpenRead()
lBytes = oFileStream.Length
Dim filecontents(lBytes) As Byte
oFileStream.Read(filecontents, 0, lBytes)
oFileStream.Close()
Return GetHash(filecontents, hasht)
Else
Return ""
End If
Catch ex As Exception
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error)
Return ""
End Try
End Function
Private Function GetStringHash(ByVal input As String, ByVal hasht As hashtype) As String
Return GetHash(Encoding.Default.GetBytes(input), hasht)
End Function
Public Function GetHash(ByRef contents As Byte(), ByVal hasht As hashtype) As String
Dim result() As Byte
Select Case hasht
Case hashtype.MD5
Dim MD5 As MD5 = MD5.Create
result = MD5.ComputeHash(contents)
Case hashtype.SHA1
Dim sha1M As New SHA1Managed
result = sha1M.ComputeHash(contents)
Case hashtype.SHA256
Dim sha256M As New SHA256Managed
result = sha256M.ComputeHash(contents)
Case hashtype.SHA384
Dim sha384M As New SHA384Managed
result = sha384M.ComputeHash(contents)
Case hashtype.SHA512
Dim sha512M As New SHA512Managed
result = sha512M.ComputeHash(contents)
End Select
Return GetByteString(result)
End Function
Public Function GetByteString(ByVal data As Byte())
Dim sBuilder As New StringBuilder()
Dim i As Integer
For i = 0 To data.Length - 1
sBuilder.Append(data(i).ToString("x2"))
Next i
Return sBuilder.ToString()
End Function
End Class
Is it a Hash Brown?It has been one crazy semester (I think the lack of activity can vouch for that). I've come up to the surface and see that a lot of the landscape has changed, take the emergence of CodeGear for example. I am hoping this is a breathe of new life that can revitalize the Delphi community and not just a last ditch effort (personally I think the BDS IDE is far better for development than VS). I am optimistic about the whole thing and hope they endure the 'rebirth process'.
As I was submerged in my own little world for a period of time, I had the need to calculate the Hash value for files. This actually turned out to server two purposes. The first being the verification of a file as original (intact) by comparing the hash value of the current and original file. Second, it turned out to be a fast way of identifying identical files. Often times a CRC is used to calculate a checksum, however I opted to make use of the System.Security.Cryptography Namespace. This Namespace has a number of useful hash functions including SHA1, SHA256 and SHA512. Surprisingly (or not) these are relatively easy to use and eliminate the need to formulate the algorithm on your own. Here it is in a couple of worlds:
Delphi:
uses
System.Security.Cryptography, System.IO;
procedure frmMain.ClearForm;
begin
txtSHA1.Text:= '';
txtSHA256.Text:= '';
txtSHA512.Text:= '';
end;
procedure frmMain.txtFileName_TextChanged(sender: System.Object; e: System.EventArgs);
begin
ToolTip1.SetToolTip(txtFileName,txtFileName.Text);
end;
procedure frmMain.btnCalculate_Click(sender: System.Object; e: System.EventArgs);
var
myCursor: System.Windows.Forms.Cursor;
oFileStream: FileStream;
lBytes: int64;
instance: FileInfo;
filecontents: Array of Byte;
result: Array of Byte;
SHA1M: SHA1Managed;
SHA256M: SHA256Managed;
SHA512M: SHA512Managed;
begin
myCursor:= Cursor;
Cursor:= Cursors.WaitCursor;
try
try
if not(txtFileName.Text='') then
begin
ErrorProvider1.SetError(btnFile,'');
instance:= FileInfo.Create(txtFileName.Text);
oFileStream:= instance.OpenRead;
lBytes:= oFileStream.Length;
SetLength(filecontents,lBytes);
oFileStream.Read(filecontents,0,lBytes);
oFileStream.Close;
SHA1M:= SHA1Managed.Create;
result:= SHA1M.ComputeHash(filecontents);
txtSHA1.Text:= Convert.ToBase64String(result);
SHA256M:= SHA256Managed.Create;
result:= SHA256M.ComputeHash(filecontents);
txtSHA256.Text:= Convert.ToBase64String(result);
SHA512M:= SHA512Managed.Create;
result:= SHA512M.ComputeHash(filecontents);
txtSHA512.Text:= Convert.ToBase64String(result);
end
else
begin
ErrorProvider1.SetError(btnFile,'Select a filename');
end;
except
on e: exception do
MessageBox.Show(e.Message, e.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
end;
finally
Cursor:= myCursor;
end;
end;
procedure frmMain.btnFile_Click(sender: System.Object; e: System.EventArgs);
begin
if (ofdFileName.ShowDialog = System.Windows.Forms.DialogResult.OK) then
begin
ClearForm;
txtFileName.Text:= ofdFileName.FileName;
end;
end;
VB:
Imports System.Security.Cryptography
Imports System.IO
Public Class frmMain
Private Sub btnFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFile.Click
If ofdFileName.ShowDialog Then
ClearForm()
txtFileName.Text = ofdFileName.FileName
End If
End Sub
Private Sub txtFileName_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtFileName.TextChanged
ToolTip1.SetToolTip(txtFileName, txtFileName.Text)
End Sub
Private Sub ClearForm()
txtSHA1.Text = ""
txtSHA256.Text = ""
txtSHA512.Text = ""
End Sub
Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click
Dim myCursor As Cursor
Dim oFileStream As System.IO.FileStream
Dim lBytes As Long
Dim result() As Byte
myCursor = Cursor
Cursor = Cursors.WaitCursor
Try
If Not (txtFileName.Text = "") Then
ErrorProvider1.Clear() 'Introduced .NET 2.0
Dim instance As New FileInfo(txtFileName.Text)
oFileStream = instance.OpenRead()
lBytes = oFileStream.Length
Dim filecontents(lBytes) As Byte
oFileStream.Read(filecontents, 0, lBytes)
oFileStream.Close()
Dim sha1M As New SHA1Managed
result = sha1M.ComputeHash(filecontents)
txtSHA1.Text = Convert.ToBase64String(result)
Dim sha256M As New SHA256Managed
result = sha256M.ComputeHash(filecontents)
txtSHA256.Text = Convert.ToBase64String(result)
Dim sha512M As New SHA512Managed
result = sha512M.ComputeHash(filecontents)
txtSHA512.Text = Convert.ToBase64String(result)
Else
ErrorProvider1.SetError(btnFile, "Select a filename")
End If
Catch ex As Exception
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
Cursor = myCursor
End Try
End Sub
End Class
This is another post done with Live Writer, I think it is pretty 'groovy'.