Md5 hash entire listbox - vb.net

As of now I can hash listbox selected item with
Public Function Md5FromString(ByVal Source As String) As String
Dim Bytes() As Byte
Dim sb As New StringBuilder()
'Check for empty string.
If String.IsNullOrEmpty(Source) Then
Throw New ArgumentNullException
End If
'Get bytes from string.
Bytes = Encoding.Default.GetBytes(Source)
'Get md5 hash
Bytes = MD5.Create().ComputeHash(Bytes)
'Loop though the byte array and convert each byte to hex.
For x As Integer = 0 To Bytes.Length - 1
sb.Append(Bytes(x).ToString("x2"))
On Error Resume Next
Next
'Return md5 hash.
Return sb.ToString()
End Function
And collect them in another listbox, but I get an error (An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll) after about 4K somewhere random as if it fails to update a label or textbox then have to edit my list and reset and i just feel there is a better way to do this.
Can someone more experienced offer some guidance in making this routine more efficient?

Not sure where your error is coming from, but you definitely don't need to be using Create() in a tight loop. Store it as a local variable and re-use it by declaring it as static (or keep the reference at class level instead):
Public Function Md5FromString(ByVal Source As String) As String
Static local_MD5 As MD5 = MD5.Create
If String.IsNullOrEmpty(Source) Then
Throw New ArgumentNullException
End If
Dim sb As New StringBuilder()
For Each b As Byte In local_MD5.ComputeHash(Encoding.Default.GetBytes(Source))
sb.Append(b.ToString("x2"))
Next
Return sb.ToString()
End Function

Ok, here is how I figured out to work better than what I was doing by a tremendous bound, I was waiting for about an hour for 4K hashes now I get 50K in mins by hashing the string as they come in from the .txt. May still be messy but it works way faster.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = ""
OpenFileDialog1.Title = "Please Select a File"
OpenFileDialog1.InitialDirectory = "C:temp"
OpenFileDialog1.ShowDialog()
Dim path As String = OpenFileDialog1.FileName
TextBox1.Text = path
Dim lines() As String = IO.File.ReadAllLines(TextBox1.Text)
For Each line In lines
ListBox1.Items.Add(Md5FromString(line) + ":" + line)
ListBox1.Refresh()
Label1.Text = ListBox1.Items.Count
Label1.Refresh()
If ListBox1.Items.Count = 1000 Then
save()
ListBox1.Items.Clear()
ListBox1.Refresh()
Label1.Text = 0
End If
Next
' ListBox1.SelectedIndex = 0
End Sub

Related

reading from txt file and writing in textbox

Can somebody help me with this, im stuck no idea what to do next
give a text file at any location in the computer it contains 15 different integers that can be repeated
make the program so that multiple repetitions of one number are not printed separately, but each number is printed exactly once
and next to it are written in which places he appeared
Imports System.IO
Public Class form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim povratnaVrijednost As DialogResult
Dim nazivDatoteke As String
Try
OpenFileDialog1.AddExtension = True
OpenFileDialog1.Multiselect = False
OpenFileDialog1.Filter = "Tekst datoteke (*.txt)|*.txt;"
povratnaVrijednost = OpenFileDialog1.ShowDialog()
If povratnaVrijednost = Windows.Forms.DialogResult.OK Then
If OpenFileDialog1.CheckFileExists = True And
OpenFileDialog1.CheckPathExists = True Then
nazivDatoteke = OpenFileDialog1.FileName
TextBox1.Text = nazivDatoteke
Dim citac As New StreamReader(nazivDatoteke)
Dim redTeksta As String = ""
Do
redTeksta = citac.ReadLine()
If Not redTeksta Is Nothing Then
RichTextBox1.Text = RichTextBox1.Text + redTeksta
End If
Loop Until redTeksta Is Nothing
citac.Close()
End If
End If
Catch ex As Exception
MsgBox("Greska prilikom otvaranja" + ex.StackTrace.ToString)
End Try
End Sub
End Class
123
Requirement #1:
give a text file at any location in the computer it contains 15 different integers that can be repeated
This requirement implies a couple of other requirements. First, you're expected to read the text file. Second, you're expected to parse the values into numbers (presumably integers).
You can use an OpenFileDialog (documentation) and specify that it can only accept text files:
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
'.FileName will be the text file that the user picked
End If
End With
End Using
To read the text file, assuming you want each line, use the File.ReadAllLines method (documentation):
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
Dim lines = IO.File.ReadAllLines(.FileName)
End If
End With
End Using
To parse the values, use the Array.ConvertAll method (documentation) and inside of the predicate use the Integer.Parse method (documentation):
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
Dim lines = IO.File.ReadAllLines(.FileName)
Dim values = Array.ConvertAll(lines, Function(line) Integer.Parse(line))
End If
End With
End Using
Keep in mind that if you wanted to validate that the lines are all valid numbers, instead of assuming that they are, this step would be different. However, you didn't specify that requirement in your original post so I'm not including how to do that.
Requirement #2:
make the program so that multiple repetitions of one number are not printed separately, but each number is printed exactly once
You can use the Random.Next method (documentation) to generate random values. Be sure to declare the new instance of the random object once so that the seed is only set once. To randomly order the values, use the OrderBy method (documentation) passing the random value in the predicate:
Private ReadOnly _random As New Random()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
Dim lines = IO.File.ReadAllLines(.FileName)
Dim values = Array.ConvertAll(lines, Function(line) Integer.Parse(line))
Dim randomlyOrderedValues = values.OrderBy(Function(value) _random.Next())
RichTextBox1.Text = String.Join(", ", randomlyOrderedValues.ToArray())
End If
End With
End Using
End Sub
Default for .AddExtension is True. Default for .Multiselect is False. I have simplified the If statement by comparing the return value of .Showdialog directly to the desired DialogResult. If the path of file don't exist the dialog will show a waring.
Always scope variables as narrowly as possible. I move the Dim nazivDatoteke to inside the If since it is not used anywhere else. StreamReaders require a Using block since they need to be disposed.
Why a RichTextBox for a text file?
As you can see getting the distince items in the array is easy, a single line of code. What is more difficult is finding the indexes in the original array, lines.
I looped through all the items in the distinct array (actually it is an IEnumerable(Of String) but that is not important to this code, it is just easier to type array in my explanation). I created a List(Of Integer) to hold the indexes of each item in the original array, lines. The startIndex where the FindIndex method of an Array is the location of the first occurrence of the String.
On each iteration of the Do loop I look for the matches to the item from the lines array. The FindIndex takes parameters (original array, index to start at, what we are looking for). It stops as soon as it finds a match and returns -1 if no matches are found. You can see the operation of this method be setting a break point and checking the variable values.
If a match is found I added that value to the list and change the startIndex to the position following the found index.
Next I used a StringBuilder to create the string to display. I chose the immediate window for testing purposes but you could show sb.ToString in a text box or add it to a ListBox.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.Filter = "Tekst datoteke (*.txt)|*.txt;"
If DialogResult.OK = OpenFileDialog1.ShowDialog Then
Dim nazivDatoteke = OpenFileDialog1.FileName
TextBox1.Text = nazivDatoteke
Dim lines = File.ReadAllLines(nazivDatoteke)
Dim distinct = lines.Distinct
For Each item In distinct
Dim lst As New List(Of Integer)
Dim startIndex = Array.IndexOf(lines, item)
Do
Dim FoundIndex = Array.FindIndex(lines, startIndex, Function(line) line = item)
If FoundIndex = -1 Then
Exit Do
Else
lst.Add(FoundIndex)
startIndex = FoundIndex + 1
End If
Loop
Dim sb As New StringBuilder
sb.Append(item)
For Each i In lst
sb.Append($" ({i})")
Next
Debug.Print(sb.ToString)
Next
End If
End Sub
This code displays the distinct items in the list and follow it with the positions (indexes) in the original list.

Reading second line of textfile and adding to datagridview

Im trying to add items from a textfile to datagridview but I only want to add the items from the second line of the textfile and Im not sure how to achieve this.
Thanks
Dim rowvalue As String
Dim cellvalue(20) As String
Dim streamReader As IO.StreamReader = New IO.StreamReader(OrderID.txt)
While streamReader.Peek() <> -1
rowvalue = streamReader.ReadLine()
cellvalue = rowvalue.Split(","c)
dgvOutput.Rows.Add(cellvalue)
End While
There are multiple ways but I think this is the simplest.
Dim textfile As New StreamReader("C:\Users\User\Desktop\Testfile.txt") 'open file
textfile.ReadLine() 'read a line and do nothing with it
dgvOutput.Rows.Add(textfile.ReadLine) ' read another line and add it to dgv
You can use:
Dim reader As New System.IO.StreamReader("C:\OrderID.txt")
Dim LinesList As List(Of String) = New List(Of String)
Do While Not reader.EndOfStream
LinesList.Add(reader.ReadLine())
Loop
reader.Close()
dgvOutput.Rows.Add(LinesList(1)) '1 is the second items from OrderID.txt
You don't need a stream reader to do this. Just System.IO.File class.
Using the index starting with one effectively skips the first line of the text file.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lines = File.ReadAllLines("C:\OrderID.txt")
For index = 1 To lines.Length - 1
Dim cells = lines(index).Split(","c)
dgvOutput.Rows.Add(cells)
Next
End Sub
The small c at the end of .Split indicates the comman is a Char not a string as .Split is expecting a Char here.

VB Can I sort multiple list boxes together using criteria from one list box

So as part of a school project I am creating a program that uses a Public Structure:
Public Structure ClientDatabase
Dim clientID As Integer
<VBFixedString(15)> Dim forename As String '15 bytes
<VBFixedString(15)> Dim surname As String '15 bytes
<VBFixedString(30)> Dim address1 As String '30 bytes
<VBFixedString(9)> Dim postcode As String '9 bytes
Dim Rdate As Date '8 bytes
<VBFixedString(1000)> Dim notes As String '1000 bytes
Dim p_homeIns As Boolean '4 bytes
Dim p_reMort As Boolean '4 bytes
Dim p_homemover As Boolean '4 bytes
Dim p_firstbuy As Boolean '4 bytes
Dim p_buylet As Boolean '4 bytes
Dim p_lifeinsur As Boolean '4 bytes
Dim p_criticalIllness As Boolean '4 bytes
Dim p_IncomeProtec As Boolean '4 bytes
End Structure
where the user can create and view clients' information in a table format. This 'table' was created using 3 list boxes. I know there are probably a million ways that this could have been done more efficiently but that's just how I've done it. Here is the code for how information is read into each list box:
filename = "D:\temp\clients.txt"
FileOpen(1, filename, OpenMode.Random, OpenAccess.Read, OpenShare.LockRead, 1103)
filelength = LOF(1)
numrecs = filelength / 1103
For index = 1 To numrecs
FileGet(1, client, index)
ListBoxClientID.Items.Add(client.clientID)
ListBoxClientID.Items.Add("")
ListBoxFname.Items.Add(client.forename)
ListBoxFname.Items.Add("")
ListBoxSname.Items.Add(client.surname)
ListBoxSname.Items.Add("")
ListBoxAddress.Items.Add(client.address1)
ListBoxAddress.Items.Add("")
Next
FileClose(1)
and I have attached a picture of how this main menu looks. Is there anyway that I could sort the Clients by, for example, their first name and then the client ID and Surname and Address would also sort accordingly so that the information is still correct?
I would suggest abandoning the Structure and go with a DataTable bound to a DataGridView which is essentially how you want to display the data anyways. That away you can serialize/deserialize the DataTable to an XML file. Take a look at this example; all I did was create a form, add a BindingSource, BindingNavigator, and DataGridView, and I added a TextBox and Button to the BindingNavigator:
Public Class Form1
Private clients As DataTable
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Create a new instance of a datatable
clients = New DataTable("Clients")
'Add your columns
clients.Columns.AddRange({
New DataColumn("client_id", GetType(Integer)) With {.AutoIncrement = True},
New DataColumn("forename") With {.MaxLength = 15},
New DataColumn("surname") With {.MaxLength = 15},
New DataColumn("address1") With {.MaxLength = 30},
New DataColumn("postcode") With {.MaxLength = 9},
New DataColumn("rdate", GetType(DateTime)),
New DataColumn("notes") With {.MaxLength = 1000},
New DataColumn("home_insurance", GetType(Boolean)),
New DataColumn("mortgage", GetType(Boolean)),
New DataColumn("home_mover", GetType(Boolean)),
New DataColumn("first_time_buyer", GetType(Boolean)),
New DataColumn("buy_let", GetType(Boolean)),
New DataColumn("life_insurance", GetType(Boolean)),
New DataColumn("critical_illness", GetType(Boolean)),
New DataColumn("income_protection", GetType(Boolean))
})
'Check if the file exists to deserialize the data
If IO.File.Exists("D:\temp\clients.xml") Then
clients.ReadXml("D:\temp\clients.xml")
End If
'Bind the controls
BindingSource1.DataSource = clients
DataGridView1.DataSource = clients
BindingNavigator1.BindingSource = BindingSource1
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Try
'Create a file if it does not exist
If Not IO.File.Exists("D:\temp\clients.xml") Then
IO.File.Create("D:\temp\clients.xml")
End If
'Serialize the data
clients.WriteXml("D:\temp\clients.xml", XmlWriteMode.WriteSchema)
Catch ex As Exception
'Display any errors
MessageBox.Show("There was an error serializing the data.", "Error", MessageBoxButtons.OK)
Console.WriteLine(ex.Message)
End Try
End Sub
Private Sub ToolStripButtonSearch_Click(sender As Object, e As EventArgs) Handles ToolStripButtonSearch.Click
If String.IsNullOrWhiteSpace(ToolStripTextBoxSearch.Text) Then
'If there is no String, remove the filter
BindingSource1.RemoveFilter()
Else
'If there is
BindingSource1.Filter =
$"forename = '{ToolStripTextBoxSearch.Text}'
OR surname = '{ToolStripTextBoxSearch.Text}'
OR CONVERT(client_id, 'System.String') = '{ToolStripTextBoxSearch.Text}'"
End If
End Sub
End Class
Firstly. I would recommend that you never use controls as your primary place to store data. It's much better to create a separate object such as a List(Of ClientDatabase) so that it can't accidentally be modified by users or bad code.
Have a read at the SOLID programming principle
With that in mind, have a look at the code below. It looks a bit different to your code, but I've added some comments along the way.
Also a good thing to get into the habit of doing, Write your methods so that, as much as possible, they do a single thing. Instead of piling all that code into a single method, separate it into separate methods such as LoadData, SortClientListByclientId, ClearListBoxes andPopulateListBoxes
'OK. First thing, this creates the list I mentioned earlier
Dim clientRecords As New List(Of ClientDatabase)
'So here is the replacement for your original method.
'Its much easier to tell what it does :-)
Private Sub WhateverOriginalMethodIs()
LoadCLientList()
SortClientListByclientID()
PopulateListboxes()
End Sub
'This method carries out the single task of reading your data
'into the list called clientRecords
Private Sub LoadClientList()
filename = "D:\temp\clients.txt"
FileOpen(1, filename, OpenMode.Random, OpenAccess.Read, OpenShare.LockRead, 1103)
filelength = LOF(1)
numrecs = filelength / 1103
For Index As Integer = 1 To numrecs
Dim client As New ClientDatabase
FileGet(1, client, Index)
clientRecords.Add(client)
Next
FileClose(1)
End Sub
'Now that the data is separated from your listbox, you can sort it
'using the method .OrderBy which takes a lambda method as its
'parameter to decide which property you want to sort by
Private Sub SortClientListByclientID()
clientRecords = clientRecords.OrderBy(Function(x) x.clientID)
End Sub
'As above, but by surname
Private Sub SortClientListByclientSurname()
clientRecords = clientRecords.OrderBy(Function(x) x.surname)
End Sub
'As above, but by address
Private Sub SortClientListByAddress()
clientRecords = clientRecords.OrderBy(Function(x) x.address1)
End Sub
'This is pretty self explanatory. A good reason for separating this
'out is so that you can re-use the code, and in future, if you want to
'change it, you only have to edit this one block of code instead of several
'if you use the code in multiple parts of you overall program
Private Sub PopulateListboxes()
ClearListBoxes()
For Each record As ClientDatabase In clientRecords
For Each client As ClientDatabase In clientRecords
AddClientToListBoxes(client)
Next
Next
End Sub
'Same again here there is a programming principle called "DRY"
'Don't Repeat Yourself :-) You can reuse this elsewhere now.
Private Sub AddClientToListBoxes(client As ClientDatabase)
ListBoxClientID.Items.Add(client.clientID)
ListBoxClientID.Items.Add("")
ListBoxFname.Items.Add(client.forename)
ListBoxFname.Items.Add("")
ListBoxSname.Items.Add(client.surname)
ListBoxSname.Items.Add("")
ListBoxAddress.Items.Add(client.address1)
ListBoxAddress.Items.Add("")
End Sub
'Finally - I added this bit to make an easy way of clearing the ListBoxes
Private Sub ClearListBoxes()
ListBoxClientID.Items.Clear
ListBoxFname.Items.Clear
ListBoxSname.Items.Clear
ListBoxAddress.Items.Clear
End Sub

datagrid for vb.net, reading from csv

I'm working on a homework assignment and I've hit a stumbling block trying to research information. My biggest problem is that I can find lots of info on just datagrids or just CSV files, but not really the two together.
My goal is to add, then average the 14th column of my datagrid after I've read it from a CSV file (on the buttonclick1 event) and to put that average into a label. My 14th column is in String and has $#,### values for that particular column.
Right now, my button1 click event does nothing at all besides putting up an error telling me that the index was out of range, that it must be a non negative number and less than the size of the collection.
So, I realize this is remedial for most of you, but I'm just at an utter loss in regards to how to proceed.
Public Class frmMain
Dim rowContents As String
Dim cellContents(20) As String
'closes stuff
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub btnImport_Click(sender As Object, e As EventArgs) Handles btnImport.Click
DataGridView1.ColumnHeadersVisible = True
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser("F:\1TrevorProjects\MedicalCSV\MedicalProviders.csv")
MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
DataGridView1.Rows.Add(currentRow)
'Dim currentField As String
'For Each currentField In currentRow
'MsgBox(currentField)
'Next
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line" & ex.Message & "is not valid and will be skipped.")
End Try
End While
MyReader.Close()
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim total As String = 0
For i As Integer = 0 To DataGridView1.RowCount - 1
total += DataGridView1.Rows(i).Cells(14).Value
Next
TextBox1.Text = total
End Sub
End Class
Two things:
If the DGV has AllowUsersToAddRows as True, your row loop will iterate one too many rows and throw a NullReferenceException
If the target column is #14, the cell count is zero based, so you should reference .Cell(13) for the value.
You can easily do the calculation as you populate the DGV:
Dim theTotal As Int32
Dim rCount As Int32
...
DataGridView1.Rows.Add(currentRow)
theTotal += Convert.ToInt32(currentRow(13))
rCount += 1
Then when the loop ends:
Dim theAvg = (theTotal / rCount )
If the data is in the CSV as formatted currency ("$123,45"), use this instead:
theTotal += Decimal.Parse(currentRow(13), NumberStyles.Currency)
Typically in a real app, you have to do something with the data, like import to a DB, add cols, drop cols etc. In such a case, I would avoid populating the DGV directly and use a DataTable. Especially, if the code was going to have to parse a formatted currency back from string in a loop.
That seems overkill for this, though.

Populating a combo box with the first word of a textfile

So I feel like im pretty close, but I also have a feeling I am mixing up StreamReader and ReadAllLines
....................................................................................
Option Strict On
Imports System.IO
Public Class Form4
Dim file As System.IO.StreamWriter
Private Sub Form4_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
file = My.Computer.FileSystem.OpenTextFileWriter("c:\devices.bat", False)
file.WriteLine("#echo off")
file.WriteLine("cd " & Form1.TextBox2.Text)
file.WriteLine("adb devices > C:\devices.txt")
file.Close()
Shell("C:\devices.bat", AppWinStyle.Hide, True, 500)
Dim output() = System.IO.File.ReadAllLines("C:\deviceinfo2.txt")
Dim Devices As String = ""
Dim line() As String = {}
For X = 1 To output.Count = -1
line = output(X).Split(New Char() {(" ")})
Devices = line(0)
ComboBox1.Items.Add(Devices)
Next
output.Close()
output.Dispose()
End Sub
End Class
........................................................................
What I am trying to have it do is to start reading on line two of devices.txt and then read the first word from each line until the text file is done.
It seems simple enough, but like I said, I think I am mixing streamreader with readalllines
Any help is appreciated
Class Test
Public Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As New StreamReader("TestFile.txt")
Dim line, firstWord As String
Dim i as Integer = 0
' Read and display lines from the file until the end of
' the file is reached.
Do
line = sr.ReadLine()
If Not (line Is Nothing) AndAlso i > 0 Then
firstWord = line.Split(" ")(i)
'do your logic
End If
i += 1
Loop Until line Is Nothing
End Using
Catch e As Exception
' Let the user know what went wrong.
End Try
End Sub
End Class
Grabbed this from MSDN and modified it. It should compile, but I didn't test it. This will loop through the lines, 1 by 1, skip the first line and grab each line's first word after. Hope this helps.