ASCII to Byte

  • Thread starter Thread starter Nik Martin
  • Start date Start date
N

Nik Martin

If I receive a message from the .net sockets class, it's a byte array. The
original message is an ASCII string,like "70,70,70,70,70,0,0,0,0". The
commas here represent individual bytes. The 70's are the ASCII code for
"F", which I need to interpret as HEX F, or 15. Is this possible without a
long, complicated lookup table?

Thanks,

Nik Martin
 
Hi Nik,
Always nice games.
This is the shortest I came up with
\\\.
Dim s As String = "70,70,70,70,70,0,0,0,0"
Dim a As String() = Split(s, ",")
Dim i As Integer
Dim b As String
For i = 0 To a.Length - 1
b = String.Concat(b, Hex(a(i)))
Next
////
I hope it works for you
Cor
 
Hi Nik,

I was going to reply to your ASCII Terminal query, but you've reposted.
Such impatience!! ;-)

|| Is this possible without a long, complicated lookup table?

Yes, lol. You use a short, uncomplicated table!

I presume that you're getting hex values, so '0'-'9', 'A'-'F' are the only
possibilities. Rather than me explaining, try the code below. :-)

If 'a' to 'f' are possibilities, add them to the table.

Regards,
Fergus

<code>
Public Module AsciiToBitArrayConversion
Private CharToNibble() As Byte

Private Sub InitAsciiToBitArray
ReDim CharToNibble(256)
'These values are reversed because
'New BitArray (Byte()) reverses the bytes.
CharToNibble (Asc("0")) = &h0
CharToNibble (Asc("1")) = &h8
CharToNibble (Asc("2")) = &h4
CharToNibble (Asc("3")) = &hC
CharToNibble (Asc("4")) = &h2
CharToNibble (Asc("5")) = &hA
CharToNibble (Asc("6")) = &h6
CharToNibble (Asc("7")) = &hE
CharToNibble (Asc("8")) = &h1
CharToNibble (Asc("9")) = &h9
CharToNibble (Asc("A")) = &h5
CharToNibble (Asc("B")) = &hD
CharToNibble (Asc("C")) = &h3
CharToNibble (Asc("D")) = &hB
CharToNibble (Asc("E")) = &h7
CharToNibble (Asc("F")) = &hF
End Sub

Public Sub TestAtoB
Dim S As String = "80FF7BC30123456789ABCDEF"
Dim Bits As BitArray = AsciiToBitArray (S)
Dim I As Integer
Dim sBytes As String = ""
For I = 0 To Bits.Length - 1
If I / 4 = I \ 4 Then sBytes = sBytes & " "
If I / 8 = I \ 8 Then sBytes = sBytes & " "
sBytes = sBytes & DirectCast _
(IIF (Bits(I) = True, "1", "0"), String)
Next
Console.WriteLine (S & vbCrLf & sBytes)
S = S & ", " & SBytes
End Sub

Public Function AsciiToBitArray (S As String) As BitArray
If CharToNibble Is Nothing Then
InitAsciiToBitArray
End If

Dim aBytes (1 + S.Length \ 2) As Byte
Dim I As Integer
For I = 1 To S.Length Step 2
Dim Hi As Integer = CharToNibble (Asc (Mid (S, I + 1, 1)))
Dim Lo As Integer = CharToNibble (Asc (Mid (S, I + 0, 1)))
aBytes (I \ 2) = CByte (Hi * 16 + Lo)
Next

Return New BitArray (aBytes)
End Function
End Module
</code>
 
Hi Nik,

I was going to reply to your ASCII Terminal query, but you've reposted.
Such impatience!! ;-)

|| Is this possible without a long, complicated lookup table?

Yes, lol. You use a short, uncomplicated table!

I presume that you're getting hex values, so '0'-'9', 'A'-'F' are the only
possibilities. Rather than me explaining, try the code below. :-)

If 'a' to 'f' are possibilities, add them to the table.

Regards,
Fergus

<code>
Public Class AsciiHexString
Private Shared CharToNibble() As Byte

Private Shared Sub Initialise
ReDim CharToNibble(256)
'These values are reversed because
'New BitArray (Byte()) reverses the bytes.
CharToNibble (Asc("0")) = &h0
CharToNibble (Asc("1")) = &h8
CharToNibble (Asc("2")) = &h4
CharToNibble (Asc("3")) = &hC
CharToNibble (Asc("4")) = &h2
CharToNibble (Asc("5")) = &hA
CharToNibble (Asc("6")) = &h6
CharToNibble (Asc("7")) = &hE
CharToNibble (Asc("8")) = &h1
CharToNibble (Asc("9")) = &h9
CharToNibble (Asc("A")) = &h5
CharToNibble (Asc("B")) = &hD
CharToNibble (Asc("C")) = &h3
CharToNibble (Asc("D")) = &hB
CharToNibble (Asc("E")) = &h7
CharToNibble (Asc("F")) = &hF
End Sub

Public Shared Function ToBitArray (S As String) As BitArray
If CharToNibble Is Nothing Then
Initialise
End If

Dim aBytes (1 + S.Length \ 2) As Byte
Dim I As Integer
For I = 1 To S.Length Step 2
Dim Hi As Integer = CharToNibble (Asc (Mid (S, I + 1, 1)))
Dim Lo As Integer = CharToNibble (Asc (Mid (S, I + 0, 1)))
aBytes (I \ 2) = CByte (Hi * 16 + Lo)
Next

Return New BitArray (aBytes)
End Function
End Class

Public Sub TestAtoB
Dim S As String = "80FF7BC30123456789ABCDEF"
Dim Bits As BitArray = AsciiHexString.ToBitArray (S)
Dim I As Integer
Dim sBytes As String = ""
For I = 0 To Bits.Length - 1
If I / 4 = I \ 4 Then sBytes = sBytes & " "
If I \ 8 = I / 8 Then sBytes = sBytes & " "
sBytes = sBytes & DirectCast _
(IIF (Bits(I), "1", "0"), String)
Next
Console.WriteLine (S & vbCrLf & sBytes)
S = S & ", " & sBytes
End Sub
</code>
 
Hello,

Cor said:
Dim s As String = "70,70,70,70,70,0,0,0,0"
Dim a As String() = Split(s, ",")
Dim i As Integer
Dim b As String
For i = 0 To a.Length - 1
b = String.Concat(b, Hex(a(i)))

Notice that it's better to use a 'StringBuilder' to compose the string.
 
Hi Herfried,
Notice that it's better to use a 'StringBuilder' to compose the string.
I agree with you
I tested it and the string builder seems really to overcome the problem from
every time allocating memory.
So therefore is beneath a more preferable approach.
\\\\
Dim s As String = "70,70,70,70,70,0,0,0,0"
Dim a As String() = Split(s, ",")
Dim i As Integer
Dim b As New System.Text.StringBuilder
For i = 0 To a.Length - 1
b.Append(Hex(a(i)))
Next
Dim y As String = b.ToString
///
;-)
Cor
 
I wasn't sure the ASCII terminal post made sense.

The problem is, I'm getting the ASCII values for the Hex character I really
need.

So what the terminal sends is a string like "FFFFF12EF0000333"

But using the socket class, I have to allocate a byte buffer, so what I get
in the Buffer is:
dim b() as byte
stream.read(b,0,16)

B(0)=70
B(1)=70
B(2)=70
B(3)=70
B(4)=70
B(5)=49
B(6)=50
etc.
etc


Which are the decimal values for the strings F, 1, 2, etc.

What I need aout of these strings is the fact that F (str(70)) is hex F (16)
 
Nik said:
I wasn't sure the ASCII terminal post made sense.

The problem is, I'm getting the ASCII values for the Hex character I really
need.

So what the terminal sends is a string like "FFFFF12EF0000333"

But using the socket class, I have to allocate a byte buffer, so what I get
in the Buffer is:
dim b() as byte
stream.read(b,0,16)

B(0)=70
B(1)=70
B(2)=70
B(3)=70
B(4)=70
B(5)=49
B(6)=50
etc.
etc


Which are the decimal values for the strings F, 1, 2, etc.

What I need aout of these strings is the fact that F (str(70)) is hex F (16)

System.Text.Encoding.ASCII.GetString(). Then just loop through the
caracters and build your byte array.

In fact, you could then use Byte.Parse with the
NumberStyles.AllowHexSpecifier to convert to the actuall byte...

Something like:

Dim returnBuffer As String = _
System.Text.Encoding.ASCII.GetString(socketBuffer)

Dim bytes(returnBuffer.Length - 1) As Byte

For i As Integer = 0 To bytes.GetUpperBound(0)
bytes(i} = Byte.Parse(returnBuffer.SubString(i, 1), _
Globalization.NumberStyles.AllowHexSpecifier)
Next

Dim bits As New BitArray(bytes)


HTH,
Tom Shelton
 
Hi Nik,

I gave you a <complete solution> in my post - didn't you try it? :-(

Take the class as given. Drop it into a file and call Sub TestAtoB. You
will see what it does. Easy.

It takes an input string. So what. Modify it for your byte array and of
you go.

Regards,
Fergus
 
Back
Top