Split String in ASCii - vba

I want to split many strings into its ASCII values.
Dim aoC(99), i As Integer
Dim W As String
W="abcd"
For i = 1 To Len(W)
aoC(i) = Asc(Mid(W, i, 1))
Next
Is there a faster method?

You can use
Dim aoC() as Byte
aoC="abcd"
This will give you a byte array of low,high bytes for the 16 bit value for each character in the string. For ascii values the high byte is 0. So to iterate the aoC for the low byte only you would use something like
For myIndex = 0 to ubound(aoC) step 2
Use the locals window to see the raw data.

Related

How do I convert integer to 4-digit hex string?

I need to convert a 2-byte signed integer into a string of it's hex equivalent, but I need the string to be 4 characters. I've tried the Hex() function but when I convert 0 or say, 10, the result is 0 or A. I need the result to be 0000 or 000A. Any tips or advice?
It is just
Dim hexS As String = i.ToString("X4")
This is well explained in the The Hexadecimal (X) Format specifier.
The 4 after the X specifies how many chars you want in the output and if there are not enough chars, the missing ones are supplied as an appropriate number of "0".
Since you also tagged the question VBA, here is a VBA way to do it
Right("0000" & Hex(i), 4)
Use
Dim i As Integer = 10
Dim hexS As String = i.ToString("X4")
If you are deadset on using Hex as opposed to string formatting then you could use:
Dim Number As Integer
Dim Output As String
Number = 10
Output = ("000" & Hex(Number))
Output = Output.Substring(Output.Length - 4, 4)
Console.WriteLine(Output)
Alternatively make use of string formatting for numbers as so:
Output = Number.ToString("X4")
Console.WriteLine(Output)
The output in both cases with be 000A.
The VB way
Format(i, "X4")
or
Hex(i).PadLeft(4, "0"c)
In Visual Studio 2015:
s = $"{i:X4}"

Converting Strings to Hex/ByteArray VB

I'm currently working on project where I am required to take a simple string of characters:
string ("Example")
and convert to an array of hex bytes:
HexByteArray(45 ,78 ,61 ,6d ,70 ,6c ,65)
in VBA I achieved this using strconv:
bytes = StrConv(id, vbFromUnicode)
Struggling to find equivalent functionality in VB, so far I have managed to create an integer equivalent using the Hex() function but as mentioned I need to store each characters hex equivalent within a byte array. Probably a simple solution, all help appreciated!
Sub GetHexString(Value As String)
Dim Bytes() As Byte = Text.Encoding.ASCII.GetBytes(Value)
' StringBuilder Capacity for 2 characters plus space per byte
With New StringBuilder(Bytes.Length * 3)
For Each B As Byte In Bytes
' note the trailing space in the format
.AppendFormat("{0:x2} ", B)
Next
Debug.Print(.ToString.Trim)
' If you want an array of strings, split on the spaces
Dim HexString() As String = Split(.ToString.Trim, " ")
End With
End Sub
Output of GetHexString("Example"):
45 78 61 6d 70 6c 65

how to get each hexadecimal value present in the text box into an array?

In my application, the users may need to add hexadecimals in the textbox during run time and I would like to get each hexadecimal value in an array by removing the spaces if there are any.
For example, the data in the textbox is "ff 00 ff 1a ff 00". I could able to get each hexadecimal as an array with the help of split. But, now I am trying to remove all the spaces as some users may enter the hexadecimals without giving the space. For example, the user my enter as "ff 00 ff1a ff 00". So, in this case the third array contains "ff1a", which is not true. I know how to remove the spaces, but cannot able to figure out the way to get each hexadecimal into an array.
'Used to split the strings based on the spaces, which is not useful
'Dim extraData As String() = Split(TextBox8.Text, " ")
'Used to remove the spaces
Dim myString = TextBox8.Text.Replace(" ", "")
Any suggestion will be appreciated.
You can use something like:
Dim input As String = TextBox1.Text
Dim list As New List(Of String)
input = input.Replace(" ", "")
For i As Integer = 0 To input.Length - 1 Step 2
list.Add(input.Substring(i, 2))
Next
Dim array = list.ToArray()
Note - The length of the input (after removing spaces) must be even. Otherwise, it may throw an exception.
If I convert the method from C# to VB.NET given in this answer:
Public Function StringToByteArray(hex As [String]) As Byte()
Dim NumberChars As Integer = hex.Length
Dim bytes As Byte() = New Byte(NumberChars / 2 - 1) {}
For i As Integer = 0 To NumberChars - 1 Step 2
bytes(i / 2) = Convert.ToByte(hex.Substring(i, 2), 16)
Next
Return bytes
End Function
Then you can call it like this:
StringToByteArray(YourInputString.Replace(" ", ""))
This will return an array of bytes and will also validate the input because it will thrown an exception if invalid characters are used in the input (like non-hex characters).
I know you already have accepted an answer, however, I'd like to suggest another alternative. I'm assuming, based on the context of your question and the example that you provided, that your intention is to parse a list of bytes, where each byte is represented by a two digit hexadecimal value.
If you use regex to find your matches, it will be more powerful. For instance, you can easily ignore all white-space characters (e.g. tabs, new-lines) and you can easily validate the data to make sure that only properly formatted bytes are in the string (i.e. 00 - FF). For instance, you could do something like this:
Dim bytes As New List(Of String)()
Dim m As Match = Regex.Match(TextBox1.Text, "^\s*((?<byte>[a-fA-F0-9]{2})\s*)*$")
If m.Success Then
Dim g As Group = m.Groups("byte")
If g.Success Then
For Each c As Capture In g.Captures
bytes.Add(c.Value)
Next
End If
Else
MessageBox.Show("Input is not properly formatted")
End If
However, if the idea is to parse the actual byte values, you can do so using Byte.Parse, like this:
Dim bytes As New List(Of Byte)()
Dim m As Match = Regex.Match(TextBox1.Text, "^\s*((?<byte>[a-fA-F0-9]{2})\s*)*$")
If m.Success Then
Dim g As Group = m.Groups("byte")
If g.Success Then
For Each c As Capture In g.Captures
bytes.Add(Byte.Parse(c.Value, NumberStyles.HexNumber))
Next
End If
Else
MessageBox.Show("Input is not properly formatted")
End If
Both of those examples use the same regex pattern to find all of the hexadecimal bytes in the string. The pattern it uses is:
^\s*((?<byte>[a-fA-F0-9]{2})\s*)*$
Here's the meaning of the regex pattern:
$ - The match must start at the beginning of the string (i.e. no invalid text can come before the bytes)
\s* - Any number of white-space characters can come before the first byte
\s - Any white-space character
* - Zero or more times
((?<byte>[a-fA-F0-9]{2})\s*)* - Any number of bytes, each separated by any number of white-space characters
( - Begins the group so that we can later apply a kleene star to the whole group (which means the whole group can repeat any number of times)
(?<byte> - Begins another, inner group which is named "byte". It is given a name so that we can easily reference the values captured by the group in the VB code.
[a-fA-F0-9]{2} - A two-digit hexadecimal byte (i.e. 00 - FF)
[a-fA-F0-9] - Any character between a and f or between A and F or between 0 and 9
{2} - There must be exactly two characters matching that specification
) - Ends the group named "byte". Notice that this named-group only captures the two actual hexadecimal digits. It does not capture any of the white-space between the bytes.
\s* - There can be any number of white-space characters after a byte
) - The ends outer group which includes a byte and all of the white-space that comes after it
* - The aforementioned kleene star meaning that the outer-group can repeat any number of times
$ - The match must end at the ending of the string (i.e. no invalid text can come after the bytes)

Convert from ULong to Integer

I´m trying to convert a list of ULONG into an array of Integers.
The problem is related to HOW discard the MSB of ULONG! I had tried all kind of operations and all of them are raising an "Overflow Exception" error:
dim MyInteger as Integer = CInt(ULong_Number)
dim MyInteger as Integer = Convert.ToInt32(ULong_Number)
dim MyInteger as Integer = Convert.ToUInt32(ULong_Number)
dim MyInteger as Integer = ULong_Number xor &HFFFFFFFF00000000 xor &HFFFFFFFF00000000
I´m trying to avoid a convertion into a temporary byte array to, after, read each 4 bytes into the integer (the LIST if huge, almost 2 million numbers).
Does anyone have any idea to implicit convert this ULONG to INTEGER?
Thanks!
If you are sure that the value of ULong_Number is not more than the maximum value of an integer (2^31 - 1, or &H7FFFFFFF), or you want to ignore any higher order bits (which would be an odd thing to do, but you are trying to fit an 8-byte number into 4 bytes), you could use this.
Dim MyInteger As Integer = CInt(ULong_Number And CULng(&H000000007FFFFFFF))

String.ToCharArray() stored in StringCollection conversion to numbers and back in VB.net

I have a string which was converted to a char array and stored in a stringcollection, how do I return the numerical value for the character in each string? How can I reverse this process, getting the character from the numerical value?
I know I could code a Select Case statement, but that would take a very long time as I need to cover every character a person could want to conceivably use in the English language, including punctuation.
Is there already a method built into vb.net for doing this?
Thanks for the help!
The Convert class has methods that can convert between characters and integers:
Dim c As Char = "A"C
Dim i As Integer = Convert.ToInt32(c)
Dim c2 As Char = Convert.ToChar(i)
To loop the values converted from the characters in a string into an array of integers:
Dim codes(theString.Length - 1) As Integer
For i As Integer = 0 to theString.Length - 1
codes(i) = Convert.ToInt32(theString.Chars(i))
Next
Try something like this:
For Each c As Char In yourString
Dim i As Int32 = DirectCast(c, Int32)
Next
Remeber that System.String implements IEnumerable<Char> so it is legal to For Each over it. And converting between a character and a number is as simple as casting between System.Char and System.Int32 (here I have shown how to get the numeric value for each character in the string).