The code gives leading zeros in hex to binary output - vb.net

The code gives additional 4 zeros, where the output should be without leading zeros. But I can't just trim it because with a different hex output it seems to produce different results. where did that four zeros come from? optionstrict on
The wrong output from the code (notice the additional leading 0000 in the wrong output in the front)
0000101001110011101011000110110111000000100000010010000001100000111111101101111101001010111110101011101001001100100101110111010011010110101101101100110000110110110000111001100100000111010011001011110110110010111111110000101011110010111010001000010100000101
The correct and expected binary should be (converted with an online hex to binary tool)
101001110011101011000110110111000000100000010010000001100000111111101101111101001010111110101011101001001100100101110111010011010110101101101100110000110110110000111001100100000111010011001011110110110010111111110000101011110010111010001000010100000101
The VB.net code I used
Private Function HexStringToByteArray(ByVal shex As String) As Byte()
Dim B As Byte() = Enumerable.Range(0, shex.Length).Where(Function(x) x Mod 2 = 0).[Select](Function(x) Convert.ToByte(shex.Substring(x, 2), 16)).ToArray()
Return Enumerable.Range(0, shex.Length).Where(Function(x) x Mod 2 = 0).[Select](Function(x) Convert.ToByte(shex.Substring(x, 2), 16)).ToArray()
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim hex As String = "0a73ac6dc0812060fedf4afaba4c9774d6b6cc36c399074cbdb2ff0af2e88505"
Dim bytes As Byte() = HexStringToByteArray(hex)
If BitConverter.IsLittleEndian Then
Array.Reverse(bytes)
End If
Dim myBA3 As New BitArray(bytes)
Dim myba3_reversed As New BitArray(myBA3.Length)
Dim count As Integer = (myBA3.Count - 1)
Dim myba3BITS As String = Nothing
For i = 0 To myBA3.Count - 1
If myBA3(i) = True Then
myba3BITS &= "1"
End If
If myBA3(i) = False Then
myba3BITS &= "0"
End If
count = (myBA3.Count - 1) - i
myba3_reversed(i) = myBA3(count)
Next i
Dim reversedBITS As String = Nothing
For i = 0 To myba3_reversed.Count - 1
If myba3_reversed(i) = True Then
reversedBITS &= "1"
End If
If myba3_reversed(i) = False Then
reversedBITS &= "0"
End If
Next i
Dim bits As String = reversedBITS
End Sub

Your input starts with "0a". If I use the Windows Calculator app in Programmer mode and enter that in HEX, the BIN output is "1010". Your code is taking each pair of hexadecimal digits and outputting eight binary digits, a buye for a byte. If you wanted to express the binary value 1010 in eight digits, what would it look like? You'd pad the value with four leading zeroes, wouldn't you? Where have you see that before? If your input doesn't have aleading zero then you need to add one. If your output does have leading zeroes and you don't want them, take them off. This is why you need to actually understand what your code is doing.

Related

Splitting string every 100 characters not working

I am having a problem where I just can't seem to get it to split or even display the message. The message variable is predefined in another part of my code and I have debugged to make sure that the value comes through. I am trying to get it so that every 100 characters it goes onto a new line and with every message it also goes onto a new line.
y = y - 13
messagearray.AddRange(Message.Split(ChrW(100)))
Dim k = messagearray.Count - 1
Dim messagefin As String
messagefin = ""
While k > -1
messagefin = messagefin + vbCrLf + messagearray(k)
k = k - 1
End While
k = 0
Label1.Text = Label1.Text & vbCrLf & messagefin
Label1.Location = New Point(5, 398 + y)
You can use regular expression. It will create the array of strings where every string contains 100 characters. If the amount of remained characters is less than 100, it will match all of them.
Dim input = New String("A", 310)
Dim mc = Regex.Matches(input, ".{1,100}")
For Each m As Match In mc
'// Do something
MsgBox(m.Value)
Next
You can use LINQ to do that.
When you do a Select you can get the index of the item by including a second parameter. Then group the characters by that index divided by the line length so, the first character has index 0, and 0 \ 100 = 0, all the way up to the hundredth char which has index 99: 99 \ 100 = 0. The next hundred chars have 100 \ 100 = 1 to 199 \ 100 = 1, and so on (\ is the integer division operator in VB.NET).
Dim message = New String("A"c, 100)
message &= New String("B"c, 100)
message &= New String("C"c, 99)
Dim lineLength = 100
Dim q = message.Select(Function(c, i) New With {.Char = c, .Idx = i}).
GroupBy(Function(a) a.Idx \ lineLength).
Select(Function(b) String.Join("", b.Select(Function(d) d.Char)))
TextBox1.AppendText(vbCrLf & String.Join(vbCrLf, q))
It is easy to see how to change the line length because it is in a variable with a meaningful name, for example I set it to 50 to get the output
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
You can use String.SubString to do that. Like this
Dim Message As String = "your message here"
Dim MessageList As New List (Of String)
For i As Integer = 0 To Message.Length Step 100
If (Message.Length < i + 100) Then
MessageList.Add(Message.SubString (i, Message.Length - i)
Exit For
Else
MessageList.Add(Message.SubString (i, 100))
End If
Next
Dim k = MessageList.Count - 1
...
Here is what your code produced with a bit of clean up. I ignored the new position of the label.
Private Sub OpCode()
Dim messagearray As New List(Of String) 'I guessed that messagearray was a List(Of T)
messagearray.AddRange(Message.Split(ChrW(100))) 'ChrW(100) is lowercase d
Dim k = messagearray.Count - 1
Dim messagefin As String
messagefin = ""
While k > -1
messagefin = messagefin + vbCrLf + messagearray(k)
k = k - 1
End While
k = 0 'Why reset k? It falls out of scope at End Sub
Label1.Text = Label1.Text & vbCrLf & messagefin
End Sub
I am not sure why you think that splitting a string by lowercase d would have anything to do with getting 100 characters. As you can see the code reversed the order of the list items. It also added a blank line between the existing text in the label (In this case Label1) and the new text.
To accomplish your goal, I first created a List(Of String) to store the chunks. The For loop starts at the beginning of the input string and keeps going to the end increasing by 10 on each iteration.
To avoid an index out of range which would happen at the end. Say, we only had 6 characters left from start index. If we tried to retrieve 10 characters we would have an index out of range.
At the end we join the elements of the string with the separated of new line.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BreakInto10CharacterChunks("The quick brown fox jumped over the lazy dogs.")
End Sub
Private Sub BreakInto10CharacterChunks(input As String)
Dim output As New List(Of String)
Dim chunk As String
For StartIndex = 0 To input.Length Step 10
If StartIndex + 10 > input.Length Then
chunk = input.Substring(StartIndex, input.Length - StartIndex)
Else
chunk = input.Substring(StartIndex, 10)
End If
output.Add(chunk)
Next
Label1.Text &= vbCrLf & String.Join(vbCrLf, output)
End Sub
Be sure to look up String.SubString and String.Join to fully understand how these methods work.
https://learn.microsoft.com/en-us/dotnet/api/system.string.substring?view=netframework-4.8
and https://learn.microsoft.com/en-us/dotnet/api/system.string.join?view=netframework-4.8

Adding digits depending on the length of a String

I want a code in vb.net with something like the following, my problem is at the last statement where I'm failing to create a 16 digits string from the missing digits which is equal to C.
Dim A as string
Dim B as a string
Dim C as integer
if len(A) = 16 then
B = A
elseif Len(A) > 16 then
B = first 16 digits of A, 'ignore the rest if the digits'
elseif len(A) < 16 then
C = 16 - len(A)
B = A & digits equal to count of C 'Making Len(B) = 16'
else
end if
I have used the .net String class which is part of the .net Framework in the System namespace.
String.Length is a property of a String. It replaces the old VB6 Len method.
String.Substring has several overloads. The one I used here has 2 integers as arguments. The first one is the starting index and the second one is the length of the string to be returned.
String.PadRight has two arguments. The first is an Integer providing the total lenght of the new string. The second is a Char provided the character to pad with. The little c following differentiates a String from a Char literal for the compiler.
You can see all the String methods and properties at https://learn.microsoft.com/en-us/dotnet/api/system.string?view=netframework-4.8
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim PaddedString As String = Get16String(TextBox1.Text)
Debug.Print(PaddedString)
End Sub
Private Function Get16String(Input As String) As String
Dim B As String = ""
If Input.Length = 16 Then
B = Input
ElseIf Input.Length > 16 Then
B = Input.Substring(0, 16)
ElseIf Input.Length < 16 Then
B = Input.PadRight(16, "0"c)
End If
Return B
End Function

Export DataGridView to text file keeping columns lined up

I am working on project for school, using VB, I am working in Visual Studio 2017.
I have a DataGridView which I need to export to a Text File.
I could use some help with an export feature from VB to a Text file. Here is the code I am using:
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim numCols As Integer = dgvApplianceList.ColumnCount
Dim numRows As Integer = dgvApplianceList.RowCount - 1
Dim strDestinationFile As String = "exportappliance.txt"
Dim tw As TextWriter = New StreamWriter(strDestinationFile)
'writing the header
For count As Integer = 0 To numCols - 1
tw.Write(dgvApplianceList.Columns(count).HeaderText)
If (count <> numCols - 1) Then
tw.Write(vbTab)
End If
Next
tw.WriteLine()
For count As Integer = 0 To numRows - 1
For count2 As Integer = 0 To numCols - 1
tw.Write(dgvApplianceList.Rows(count).Cells(count2).Value)
If (count2 <> numCols) Then
tw.Write(vbTab)
End If
Next
tw.WriteLine()
Next
tw.Close()
End Sub
Since you are writing to a “text” file, one way to line up text properly can be accomplished using spaces as others have suggested. This would require that you have a “defined” column “width” for each column. Using your picture as an example, column 0 (zero) would be “Appliance Type” and we could give that column a max “width” of… say twenty five (25) characters wide. Column 2 “kwh” could be set with a maximum column width of 15 and so on for each column.
With the “column widths” established, it should be a simple matter of adding X number of spaces needed to fill the string to the columns width. Example, to make sure column 2 lines up with the next column 2, each column 1 string MUST be all the same length. By filling each column 1 string with spaces to “fill” the string to column 1’s length, will ensure column 2’s text will line up correctly. Obviously, the same logic applies to subsequent columns.
The GetBufferedString method (below) demonstrates one way to buffer the strings to a specified column width. The method takes a string originalString, an int maxLength and a justification type. The method will return a string of length maxLength such that, if the justification type is LEFT, the method will fill the given string with spaces at the end. If the justification type is RIGHT, the method will return a string of maxLength such that spaces are added to the front of the string. Finally, if the justification type is CENTER, then the method will return a string with half the spaces in front of the string and the other half at the end. If the given string’s length is greater than maxLength, then the returned string will be a maxLength truncation of the given string.
This should enable you to set each columns justification type independently. The code below simply sets each rows justification type to right.
This is an example and I hope it helps, however there is no error checking for a possible mismatch on the number of actual columns in the grid and the number of column widths.
Some global variables… an integer array columnLengths is used to hold each columns width… also an enumeration for the justification type; RIGHT, LEFT, CENTER.
Dim columnLengths(6) As Integer
Enum JustifyType
LEFT
RIGHT
CENTER
End Enum
Set each columns width…
Private Sub FillColumnLength()
columnLengths(0) = 25
columnLengths(1) = 12
columnLengths(2) = 12
columnLengths(3) = 12
columnLengths(4) = 12
columnLengths(5) = 12
End Sub
An updated save button click event to use the GetBufferedString method.
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim numCols As Integer = dgvApplianceList.ColumnCount
Dim numRows As Integer = dgvApplianceList.RowCount - 1
Dim strDestinationFile As String = "D:\Test\exportappliance.txt"
Dim tw As TextWriter = New StreamWriter(strDestinationFile)
Dim textToOutput = ""
For count As Integer = 0 To numCols - 1
textToOutput = GetBufferedString(dgvApplianceList.Columns(count).HeaderText, columnLengths(count), JustifyType.CENTER)
tw.Write(textToOutput)
Next
tw.WriteLine()
For count As Integer = 0 To numRows - 1
For count2 As Integer = 0 To numCols - 1
textToOutput = GetBufferedString(dgvApplianceList.Rows(count).Cells(count2).Value, columnLengths(count2), JustifyType.RIGHT)
tw.Write(textToOutput)
Next
tw.WriteLine()
Next
tw.Close()
End Sub
Finally, the GetBufferedString method.
Private Function GetBufferedString(originalString As String, maxLength As Int16, justifyType As JustifyType) As String
If (originalString.Length < maxLength) Then
Dim bufString = Space(maxLength - originalString.Length)
Select Case justifyType
Case JustifyType.LEFT
Return originalString + bufString
Case JustifyType.RIGHT
Return bufString + originalString
Case JustifyType.CENTER
Dim halfString = bufString.Substring(bufString.Length / 2)
originalString = halfString + originalString
bufString = Space(maxLength - originalString.Length)
Return originalString + bufString
Case Else
Return ""
End Select
Else
Return originalString.Substring(0, maxLength)
End If
End Function
Hope this helps.

Visual Basic "Index was outside the bounds of the array" (Mean Calculator Program)

I'm trying to make a Mean Calculator (program that adds several items together (seperated by ",") and divides them by the number of items there, also known as Average). I'm going to school to learn Visual Basic and other languages like C# and Web Development, so I think eventually I'll learn this there, but I don't want to wait. I say that if I can learn something before school, then school will be refinery and mastery.
Here's the code, as it stands. (Visual Studio 13).
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim dblDivide As Double
Dim Input As New String = txtInput.Text
Dim Delimeter As Char = ","
Dim Substrings() = Input.Split(Delimeter)
Dim dblTotal As Double
Dim dblMean As Double
Double.TryParse(txtDivideBy.Text, dblDivide)
For Each substring In Substrings
dblTotal = substring(0) + substring(1)
dblMean = dblTotal / dblDivide
Next
lblMean.Text = dblMean.ToString("N2")
End Sub
Any time I try to run the code, using the numbers 2 2 and 2 (which should return 2, ((2+2)/2) = 2), line 13 returns the IndexOutOfRangeException. Eventually I want to change the program so instead of using a "Divide By" input (txtDivideBy.Text and dblDivide), I want it to divide it by the number of substrings. I tried replacing "dblDivide" in line 14 with "Substrings()" and it gave me another error.
You should be getting an error on the second line because of your use of New. This is not necessary for declaring the string.
Dim Input As New String = txtInput.Text
Your index out of bounds is because you're trying to access a sub element of substring as though it were an array. But it's not, it's a string. For Each iterates over each element in Substrings and sets substring to Substrings(i) where i is the current index. So, just keep adding substring to dblTotal to get your total.
For Each substring In Substrings
dblTotal = dblTotal + subString
Next
You don't need to divide the total for every iteration of the loop, so move it outside of the loop.
dblMean = dblTotal / dblDivide
To get the number of items in the Substrings array, you can use the Length property of an array.
dblMean = dblTotal / Substrings.Length
Complete modified code.
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim Input As String = txtInput.Text
Dim Delimeter As Char = ","
Dim Substrings() = Input.Split(Delimeter)
Dim dblTotal As Double
Dim dblMean As Double
For Each substring In Substrings
dblTotal = dblTotal + substring
Next
dblMean = dblTotal / Substrings.Length
lblMean.Text = dblMean.ToString("N2")
End Sub
The Exception is from accessing the second character of the one character string: substring(1)
Learning about LINQ might be a bit more useful in the long run:
Dim query = From s In Split(txtInput.Text, ",") Select Val(s)
lblMean.Text = query.Average.ToString("N2")
or a bit shorter
lblMean.Text = Format(Split(txtInput.Text, ",").Average(AddressOf Val), "N2")
The Val function returns 0 if no numbers are found in the string.

How do I get an Ascii to warp to a certain value after it has past 122?

I am trying to write an encryption program. The problem I am facing is that I am converting the text to ascii and then adding on the offset. However when it goes past the letter 'z' I want it to warp back to 'a' and go from there.
Sub enc()
Text = TextBox1.Text
finalmessage = ""
letters = Text.ToCharArray
offset = ComboBox1.SelectedItem
For x = LBound(letters) To UBound(letters)
finalmessage = finalmessage + Chr(Asc(letters(x)) + offset)
Next
TextBox2.Text = finalmessage
End Sub
I guess to make it easy to decode afterwards, you should to it somewhat in the line of base64 encoding, first encoding everything to a normalized binary string, then encode in the range you want (since using binary, it has to be something that fits with 2^X).
To match your range, i used a baseset of 32, and a simple encoding decoding example (a bit more verbose that it should be, perhaps)
Module Module1
Dim encodeChars As String = "abcdefghijklmnopqrstuvwxyzABCDEF" ' use 32 as a base
Function Encode(text As String) As String
Dim bitEncoded As String = ""
Dim outputMessage As String = ""
For Each ch As Char In text.ToCharArray()
Dim i As Integer = Convert.ToByte(ch)
bitEncoded &= Convert.ToString(i, 2).PadLeft(8, "0"c)
Next
While bitEncoded.Length Mod 5 <> 0
bitEncoded &= "0"
End While
For position As Integer = 0 To bitEncoded.Length - 1 Step 5
Dim range As String = bitEncoded.Substring(position, 5)
Dim index As Integer = Convert.ToInt32(range, 2)
outputMessage &= encodeChars(index).ToString()
Next
Return outputMessage
End Function
Function Decode(encodedText As String) As String
Dim bitEncoded As String = ""
Dim outputMessage As String = ""
For Each ch In encodedText
Dim index As Integer = encodeChars.IndexOf(ch)
If index < 0 Then
Throw New FormatException("Invalid character in encodedText!")
End If
bitEncoded &= Convert.ToString(index, 2).PadLeft(5, "0"c)
Next
' strip the extra 0's
While bitEncoded.Length Mod 8 <> 0
bitEncoded = bitEncoded.Substring(0, bitEncoded.Length - 1)
End While
For position As Integer = 0 To bitEncoded.Length - 1 Step 8
Dim range As String = bitEncoded.Substring(position, 8)
Dim index As Integer = Convert.ToInt32(range, 2)
outputMessage &= Chr(index).ToString()
Next
Return outputMessage
End Function
Sub Main()
Dim textToEncode As String = "This is a small test, with some special characters! Just testing..."
Dim encodedText As String = Encode(textToEncode)
Dim decodedText As String = Decode(encodedText)
Console.WriteLine(textToEncode)
Console.WriteLine(encodedText)
Console.WriteLine(decodedText)
If Not String.Equals(decodedText, textToEncode) Then
Console.WriteLine("Encoding / decoding failed!")
Else
Console.WriteLine("Encoding / decoding completed succesfully!")
End If
Console.ReadLine()
End Sub
End Module
this then gives the following output?
This is a small test, with some special characters! Just testing...
krugsCzanfzsayjaonwwcBdmebAgkCBufqqhoAlunaqhgBBnmuqhgCdfmnuwcBbamnugcCtbmnAgkCtteeqeuDltoqqhizltoruwCzzofyxa
This is a small test, with some special characters! Just testing...
Encoding / decoding completed succesfully!