VB.NET MD5 Comparing using large files - vb.net

I'm trying to create a program in VB.NET 2010 that has a simple functionality.
It has to compare thousands of MD5 Hashes stored in a text file to current file MD5 Hash that program is automatically calculating while opening the file.
Like a antivirus scanner.
Actually my program use ReadAllText system to add all hashes from text file to a textbox and then it compare them.
Everyting is okay when Md5 database (that text file with hashes) is small but when the file get bigger, my program simply freezes after opening so I decided to use ReadLine instead of ReadAllText.
Now I can't use textbox any longer so give me a way how I can compare them.
I tried a way but it don't seem to work.
Here is my code using ReadLine.
Problem is on If Read contains(buff.tostring) it used to be
If textbox.text contains (buff.toString)
Here is the code
Try
TextBox2.Text = e.FullPath
ListBox3.Items.Add(TextBox2.Text.ToString)
Me.OpenFileDialog1.FileName = ""
Dim reader As StreamReader = New StreamReader("def.txt")
Dim read = reader.ReadLine()
Dim md5 As New MD5CryptoServiceProvider
Dim f As New FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read, &H2000)
f = New FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read, &H2000)
md5.ComputeHash(f)
Dim hash As Byte() = md5.Hash
Dim buff As New StringBuilder
Dim hashByte As Byte
For Each hashByte In hash
buff.Append(String.Format("{0:X2}", hashByte))
Next
f.Close()
If read.Contains(buff.ToString) Then
Me.OpenFileDialog1.FileName = e.FullPath
Form2.ShowDialog()
End If
Catch exception1 As Exception
ProjectData.SetProjectError(exception1)
Dim ex As Exception = exception1
ProjectData.ClearProjectError()
End Try

I would first create functions to split the functionality. It's a lot easier to understand the code afterward.
Store the hashes in a list, this list can then be cached is needed.
Try
TextBox2.Text = e.FullPath
ListBox3.Items.Add(TextBox2.Text.ToString)
Me.OpenFileDialog1.FileName = ""
Dim allHash As List(Of String) = GetAllHash()
Dim curHash As String = GetFileHash(e.FullPath)
If allHash.Contains(curHash) Then
Me.OpenFileDialog1.FileName = e.FullPath
Form2.ShowDialog()
End If
Catch exception1 As Exception
ProjectData.SetProjectError(exception1)
Dim ex As Exception = exception1
ProjectData.ClearProjectError()
End Try
Function GetAllHash() As List(Of String)
' Store the data in a list instead
Return System.IO.File.ReadAllLines("def.txt").ToList()
End Function
Function GetFileHash(ByVal filename As String) As String
Dim md5 As New MD5CryptoServiceProvider
' Only open the file once
Dim f As New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, &H2000)
md5.ComputeHash(f)
Dim hash As Byte() = md5.Hash
Dim buff As New StringBuilder
For Each hashByte As Byte In hash
buff.Append(String.Format("{0:X2}", hashByte))
Next
f.Close()
Return buff.ToString()
End Function
I didn't compile this code, this is just a example to show you what can be done.

Related

Parsing CSV from stream with TextFieldParser always reaches EndOfData

During parsing CSV file as a stream from Azure Blob, TextFieldParser always reaches EndOfData immediately, without any data read. The same code, but with the path to same physical file instead of stream works.
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(AzureStorageConnection)
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("containername").ListBlobs().OfType(Of CloudBlockBlob)
For Each blb In BlobList
Dim myList As New List(Of MyBusinessObject)
Using memoryStream = New MemoryStream()
blb.DownloadToStream(memoryStream)
Using Reader As New FileIO.TextFieldParser(memoryStream)
Reader.TextFieldType = FileIO.FieldType.FixedWidth
Reader.SetFieldWidths(2, 9, 10)
Dim currentRow As String()
While Not Reader.EndOfData
Try
currentRow = Reader.ReadFields()
myList.Add(New GsmXFileRow() With {
' code to read currentRow and add elements to myList
})
Catch ex As FileIO.MalformedLineException
End Try
End While
End Using
End Using
Next
I have also tried to convert MemoryStream to TextReader
Dim myTextReader As TextReader = New StreamReader(memoryStream)
and then passing myTextReader into TextFieldParser, but this does not work either.
Using Reader As New FileIO.TextFieldParser(myTextReader)
I see this:
Value of Length property equals file size
and this:
'Position` property has same value
That means at the start of the loop, the MemoryStream has already advanced to the end of the stream. Just set Position back to 0, and you should be in a better place.
However, there may be another issue here, too. That stream data is binary with some unknown encoding. The TextFieldParser wants to work with Text. You need a way to give the TextFieldParser information about what encoding is used.
In this case, I recommend a StreamReader. This type inherits from TextReader, so you can use it with the TextFieldParser :
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(AzureStorageConnection)
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("containername").ListBlobs().OfType(Of CloudBlockBlob)
Dim myList As New List(Of MyBusinessObject)
For Each blb In BlobList
'Several constructor overloads allow you to specify the encoding here
Using blobData As New StreamReader(New MemoryStream())
blb.DownloadToStream(blobData.Stream)
'Fix the position problem
blobData.Stream.Position = 0
Using Reader As New FileIO.TextFieldParser(blogData)
Reader.TextFieldType = FileIO.FieldType.FixedWidth
Reader.SetFieldWidths(2, 9, 10)
Dim currentRow As String() = Reader.ReadFields()
While Not Reader.EndOfData
Try
myList.Add(New GsmXFileRow() With {
' code to read currentRow and add elements to myList
})
currentRow = Reader.ReadFields()
Catch ex As FileIO.MalformedLineException
End Try
End While
End Using
End Using
Next

Can't read an XML in Stream

I have a little problem with an XML file and a Stream. I create and save an XML file in a Stream, encrypt the Stream and then save it to a normal file.
I want to read this XML, however I can only do this if I use a FileStream and write a decrypted file to disk.
Is there a way to decrypt and keep this file in memory?
This is my code:
XMLDecriptato = New MemoryStream()
Using stream_readerX As New StreamReader(XMLDecriptato, Text.Encoding.UTF8)
XMLDecriptato.SetLength(0)
Dim FStreamCrypted As FileStream = File.Open(varTitolo, FileMode.Open, FileAccess.Read)
FStreamCrypted.Seek(0, SeekOrigin.Begin)
CryptStream(Pass, FStreamCrypted, XMLDecriptato, Type.Decrypt)
'try to read the stream
Dim xDocumentX As New XmlDocument()
xDocumentX.Load(stream_readerX) 'here is the error
End Using
It keeps saying that the Stream is closed. I have tried also another way. The only one that works is to write the stream to the hard disk with a FileStream.
And that is the Encrypt/Decrypt Sub:
Public Sub CryptStream(ByVal Psw As String, ByVal IN_Stream As Stream, ByVal OUT_Stream As Stream, ByVal CrtType As CryptType)
Dim AES_Provider As New AesCryptoServiceProvider()
Dim Key_Size_Bits As Integer = 0
For i As Integer = 1024 To 1 Step -1
If (aes_provider.ValidKeySize(i)) Then
Key_Size_Bits = i
Exit For
End If
Next i
Dim Block_Size_Bits As Integer = AES_Provider.BlockSize
Dim Key() As Byte = Nothing
Dim IV() As Byte = Nothing
Dim Salt() As Byte = "//my salt//"
MakeKeyAndIV(Psw, Salt, Key_Size_Bits, Block_Size_Bits, Key, IV)
Dim Crypto_Transform As ICryptoTransform = Nothing
Select Case CrtType
Case CryptType.Encrypt
Crypto_Transform = AES_Provider.CreateEncryptor(key, iv)
Case CryptType.Decrypt
Crypto_Transform = AES_Provider.CreateDecryptor(key, iv)
End Select
If Crypto_Transform Is Nothing Then Exit Sub
Try
Using Crypto_Stream As New CryptoStream(OUT_Stream, Crypto_Transform, CryptoStreamMode.Write)
Const Block_Size As Integer = 1024
Dim Buffer(Block_Size) As Byte
Dim Bytes_Read As Integer
Do
Bytes_Read = IN_Stream.Read(Buffer, 0, Block_Size)
If (Bytes_Read = 0) Then Exit Do
Crypto_Stream.Write(Buffer, 0, Bytes_Read)
Loop
End Using
Catch ex As Exception
End Try
Crypto_Transform.Dispose()
End Sub
It turns out that when CryptoStream.Dispose() is called by the Using/End Using block, the CryptoStream also disposes the underlying stream (in this case your MemoryStream). This behaviour can be confirmed by checking Microsoft's Reference Source.
Since the CryptoStream doesn't have a LeaveOpen flag like the StreamReader does since .NET 4.5 and up, I removed the Using block and wrote the necessary calls on my own for your method.
The changes:
Public Sub CryptStream(ByVal Psw As String, ByVal IN_Stream As Stream, ByVal OUT_Stream As Stream, ByVal CrtType As CryptType, Optional ByVal LeaveOpen As Boolean = False)
...code...
Try
Dim Crypto_Stream As New CryptoStream(OUT_Stream, Crypto_Transform, CryptoStreamMode.Write)
Const Block_Size As Integer = 1024
Dim Buffer(Block_Size) As Byte
Dim Bytes_Read As Integer
Do
Bytes_Read = IN_Stream.Read(Buffer, 0, Block_Size)
If (Bytes_Read = 0) Then Exit Do
Crypto_Stream.Write(Buffer, 0, Bytes_Read)
Loop
If Crypto_Stream.HasFlushedFinalBlock = False Then Crypto_Stream.FlushFinalBlock()
If LeaveOpen = False Then
Crypto_Stream.Dispose()
End If
Catch ex As Exception
End Try
...code...
End Sub
And since data will be fed into the MemoryStream its position will have changed, so you have to reset that too before loading the XML document:
XMLDecriptato = New MemoryStream()
Using stream_readerX As New StreamReader(XMLDecriptato, System.Text.Encoding.UTF8)
Dim FStreamCrypted As FileStream = File.Open(OpenFileDialog1.FileName, FileMode.Open, FileAccess.Read)
CryptStream(Pass, FStreamCrypted, XMLDecriptato, CryptType.Decrypt, True) 'True = Leave the underlying stream open.
XMLDecriptato.Seek(0, SeekOrigin.Begin) 'Reset the MemoryStream's position.
Dim xDocumentX As New XmlDocument()
xDocumentX.Load(stream_readerX)
End Using
As you might have noticed I removed the FStreamCrypted.Seek(0, SeekOrigin.Begin) line. This was because you've just opened the stream and done nothing with it, so the position will already be at 0.
Hope this helps!

Vb.net the process cannot access the file because it is being used by another process

Hello i wanted to open an csv file and write text in it.
Here is the code:
Try
Dim path As String = "C:\Users\daaemoon\Desktop\Test.csv"
Dim reader As StreamReader = New System.IO.StreamReader(File.OpenRead(path))
Dim sw As New StreamWriter(path)
Dim s As String = String.Empty
While reader.Peek() >= 0
Dim line As String = reader.ReadLine()
Dim values As String() = line.Split(";"c)
listforfalsecsv.Add(values(0))
s = s + line + Chr(10)
End While
reader.Close()
sw.Write(s)
sw.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
i got the error by the following line:
Dim sw As New StreamWriter(path)
If i use the method reader.dispose() after that line Dim reader As StreamReader = New System.IO.StreamReader(File.OpenRead(path))
i come to the while loop, but than i got an error: From an closen Textreader could not been read.
I need help, please help me.

Web Browser Filter

I would like to have a list of websites (each on a different line) that the web browser will check when navigated and if it is the current url then it will navigate back. Below is some code that I have currently have created and fails because it doesn't check each line of text and below that is some code that also check text with current text.
Using sr As New StreamReader("website_lists.txt")
Dim lined As String
lined = sr.ReadToEnd()
Dim scanbox As New TextBox
scanbox.Multiline = True
Dim buff As StringBuilder = New StringBuilder
For Each line In lined
If TextBox1.Text.Contains(scanbox.Text) Then
webview.GoBack()
MsgBox("Infected website! For your own sake stay away!")
End If
Next
End Using
End Sub
Some code that kinda does the same thing:
Dim md5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
Dim f As FileStream = New FileStream(ListBox1.SelectedItem, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
f = New FileStream(ListBox1.SelectedItem, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
md5.ComputeHash(f)
Dim hash As Byte() = md5.Hash
Dim buff As StringBuilder = New StringBuilder
Dim hashByte As Byte
For Each hashByte In hash
buff.Append(String.Format("{0:X2}", hashByte))
Next
If scanbox.Text.Contains(buff.ToString) Then
Have any suggestions or help? Thanks in advance.
I would suggest File.Readlines... More information here on this method. Also your declaring a new textbox but the text is never set which means the contains wont work... Another suggestion, turn Option Strict On its your friend.
' Loop over lines in file.
For Each line As String In File.ReadLines("yourfile")
If TextBox1.Text.Contains(line) Then
webview.GoBack()
MsgBox("Infected website! For your own sake stay away!")
Exit For
End If
Next

How do I reload the formatted text into RTB?

I have a RTB in VB.NET, and put an event handler to save the formatted text into a file after encrypting it. However, I can't figure out how to reload the formatting - when I open it, it shows the symbols of formatting instead of formatted text. Here's my code:
Dim FileName As String = TextBox1.Text
File.Delete(FileName)
Dim EncryptElement As New TripleDESCryptoServiceProvider
EncryptElement.Key = {AscW("B"c), AscW("A"c), AscW("1"c), AscW("R"c), AscW("3"c), AscW("9"c), AscW("G"c), AscW("V"c), AscW("5"c), AscW("S"c), AscW("P"c), AscW("0"c), AscW("L"c), AscW("Z"c), AscW("4"c), AscW("M"c)} '128 bit Key
EncryptElement.IV = {AscW("N"c), AscW("B"c), AscW("5"c), AscW("3"c), AscW("G"c), AscW("L"c), AscW("2"c), AscW("Q"c)} ' 64 bit Initialization Vector
Dim fStream As FileStream = File.Open(FileName, FileMode.OpenOrCreate)
Dim cStream As New CryptoStream(fStream, New TripleDESCryptoServiceProvider().CreateEncryptor(EncryptElement.Key, EncryptElement.IV), CryptoStreamMode.Write)
Dim sWriter As New StreamWriter(cStream)
sWriter.WriteLine(RichTextBox1.Rtf)
sWriter.Close()
cStream.Close()
fStream.Close()
The above code is for saving, and the below code is for opening.
Dim FileName As String = TextBox1.Text
Dim DecryptElement As New TripleDESCryptoServiceProvider
DecryptElement.Key = {AscW("B"c), AscW("A"c), AscW("1"c), AscW("R"c), AscW("3"c), AscW("9"c), AscW("G"c), AscW("V"c), AscW("5"c), AscW("S"c), AscW("P"c), AscW("0"c), AscW("L"c), AscW("Z"c), AscW("4"c), AscW("M"c)}
DecryptElement.IV = {AscW("N"c), AscW("B"c), AscW("5"c), AscW("3"c), AscW("G"c), AscW("L"c), AscW("2"c), AscW("Q"c)}
Dim fStream As FileStream = File.Open(FileName, FileMode.OpenOrCreate)
Dim cStream As New CryptoStream(fStream, New TripleDESCryptoServiceProvider().CreateDecryptor(DecryptElement.Key, DecryptElement.IV), CryptoStreamMode.Read)
Dim sReader As New StreamReader(cStream)
Dim DecryptedData As String = ""
DecryptedData = sReader.ReadToEnd
RichTextBox1.AppendText(DecryptedData)
RichTextBox1.Enabled = True
Button1.Text = "OK"
sReader.Close()
cStream.Close()
fStream.Close()
Where is the problem?
You need RichTextBox1.SaveFile(SomeStream, RichTextBoxStreamType) I think StreamWriter is stuffing it up.
Oh and seeing as you just gave the world the keys for your encryption you might want to come up with a new one...
Added after comment not proven though.
Replace these two lines in your save routine
Dim sWriter As New StreamWriter(cStream)
sWriter.WriteLine(RichTextBox1.Rtf)
with
RichTextBox1.SaveFile(cStream,RichTextBoxStreamType.RichText);
and get rid of swriter.Close()
I think.