Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

vb.net convert bytes in an byte array to ascii

Posted on 2010-11-18
7
Medium Priority
?
922 Views
Last Modified: 2012-05-10
Hi experts,

I have a blob in a mysql table that i have read into a byte() array.

The 'blob' is defined as

char name[64];

in the c++ code that creates the blob.

and the data is located in offset 0004 in the byte array

as an example, the name stored is 'Nosfentora'

i'm trying to decode the data therein and get it 'human' readable.

So far i've got the following code (see below - i'm using vb.net, but can read c++ fairly well.)

if i do

ConvertHEXToASCII(Hex(ByteToXBit(data,4,64,64)))
i get

Nosfento

as output.

if 8 bits = 1 byte, and the ToUInt64 processes 8 bytes, shouldn't that be all 64 bits in the array name[64]?

What am i missing?

Thanks!!

Public Function ConvertHEXToASCII(ByVal hextext As String) As String
        Dim value As String = ""
        Dim num As String = ""

        ' process the hex string in reverse order
        For y = Len(hextext) To 1 Step -1
            num = Mid(hextext, y - 1, 2)
            value += Chr(Val("&h" & num))
            y -= 1
        Next
        Return value
    End Function

Public Function ByteToXBit(ByVal data() As Byte, ByVal offset As Integer, ByVal bytes As Integer, ByVal num_bits As Integer) As Long

        If data.Length = 19568 And offset >= 2384 Then
            offset -= 36
        End If

        Select Case num_bits
            Case 8
                Return CByte(data(offset))
            Case 16
                Return BitConverter.ToUInt16(data, offset)
            Case 32
                Return BitConverter.ToUInt32(data, offset)
            Case 64
                Return BitConverter.ToUInt64(data, offset)
        End Select

    End Function

Open in new window

0
Comment
Question by:sgaggerj
  • 4
  • 3
7 Comments
 
LVL 5

Expert Comment

by:Barsham
ID: 34169026
Hi,

If you check the help about BitConverter
http://msdn.microsoft.com/en-us/library/system.bitconverter.touint64(VS.96).aspx

It will tell you this :

1- Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.

2- A 64-bit unsigned integer formed by the eight bytes beginning at startIndex.


I think it will get first 8 element from StartIndex. The Result is up to 64bit integer not the input.

0
 
LVL 1

Author Comment

by:sgaggerj
ID: 34172496
ok, so was i confused about the size of the array, it's name[64], 64 bytes?


so how would i go about modifying the code i have to get it to return the correct long value of name[64] and name[32] ?

0
 
LVL 5

Expert Comment

by:Barsham
ID: 34178151
char name[64];
->  64 bytes * 8 = 512 bits

Could u put sample data ? maybe we can make better algorythm to decrypt data.
I think it there should be  a simpler way to do this.

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:sgaggerj
ID: 34179932
Here is the data from the 'Nosfentora' example above (and a couple of others)

offset 4 to 67 in the blob (this data is stored in my app as a byte() )

78 111 115 102 101 110 116 111 114 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ' name is 'Nosfentora'
83 104 111 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ' name is 'Shor'
84 104 105 115 105 115 116 104 101 109 97 120 108 101 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ' name is 'Thisisthemaxlen'

the maximum length of a name that can be stored here is 15 characters, the shortest 4 (determined by client)

if i do
converthextoascii(hex(bytetoxbit(data,4,8)))
i get 'Nosfento'

if i do
converthextoascii(hex(bytetoxbit(data,4+8,8)))
i get  'ra'

if i do both

converthextoascii(hex(bytetoxbit(data,4+8,8))) + converthextoascii(hex(bytetoxbit(data,4,8)))
i get 'Nosfentora'

so i'm able to re-create the name, however to make it a little more complicated, I need to be able to do the following

dim name as string = ConvertHexToAscii(Hex(SelectedChar.CharacterProfile.Stat("name"))) (see below for Stat() )

The more I'm playing with it, the more I think that I'm going to have to do it in two parts as Hex() doesn't seem to be able to take as large a number as I would need to pass to it, but i know i'm probably missing something.


'my code has changed a little bit, this is what i'm using currently for ByteToXBit:

Public Function ByteToXBit(ByVal data() As Byte, ByVal offset As Integer, ByVal bytes As Integer) As Long

        If data.Length = 19568 And offset >= 2384 Then
            offset -= 36
        End If

        Select Case bytes
            Case 1
                Return CByte(data(offset)) ' 8
            Case 2
                Return BitConverter.ToUInt16(data, offset) ' 16
            Case 3, 4
                Return BitConverter.ToUInt32(data, offset) ' 32
            Case 8
                Return BitConverter.ToUInt64(data, offset) ' 64
        End Select

    End Function

Public Function ConvertHEXToASCII(ByVal hextext As String) As String
        Dim value As String = ""
        Dim num As String = ""

        ' process the hex string in reverse order
        For y = Len(hextext) To 1 Step -1
            num = Mid(hextext, y - 1, 2)
            value += Chr(Val("&h" & num))
            y -= 1
        Next
        Return value
    End Function

' Excerpt from Data.XML that Stat uses to find the offset, stat name and # bytes
<Profile>0000;uint32;checksum;4
    0004;char;name;64
    0068;char;last_name;32</Profile

Public Property Stat(ByVal stat_name As String) As Object
        
        ' stat_name without [] if any
        ' see data.xml 'Profile'
        ' offset;data type;stat name;bytes
        Get
            Dim stats() As String = Split(GetData("Profile"), vbLf)
            Dim selected_stat() As String = {}

            For Each _stat As String In stats
                Dim _stats() As String = Split(_stat, ";")
                If LCase(CleanString(_stats(2))) = (LCase(stat_name)) Then
                    selected_stat = _stats
                    Exit For
                End If
            Next

            If selected_stat.Length = 0 Then Return "ERROR"

            Dim val As String = ""

            If stat_name = "name" Then
                Dim offset As Integer = CInt(CleanString(selected_stat(0))) ' in the case of 'name' the offset is 4
                ' Here I need to return a value that if i call
                ' .stat("name") i can use ConvertHEXToAscii(Hex(.stat("Name"))) and get the full name
                val = ByteToXBit(character_profile, offset, 8) ' this returns 'Nosfento' when converted to ascii
            Else
                val = ByteToXBit(character_profile, CInt(CleanString(selected_stat(0))), CInt(CleanString(selected_stat(3))))
            End If
                      
            ' cover the non-conforming values of certain stats here
            If stat_name = "race" Then
                If val = 330 Then 
                    Return 15
                ElseIf val = 130 Then 
                    Return 14
                ElseIf val = 522 Then 
                    Return 17
                ElseIf val = 128 Then
                    Return 13
                Else
                    Return val
                End If
            Else
                Return val
            End If

        End Get
        Set(ByVal value As Object)
            ' TODO: finish me
        End Set
    End Property

Public Function CleanString(ByVal dirty_string) As String

        ' Add more as they are found
        Dim remove_these() As String = {vbCrLf, vbLf, vbTab, vbCr, vbCrLf, vbNewLine}
        Dim clean_string As String = dirty_string

        For Each remove_this As String In remove_these
            clean_string = Replace(clean_string, remove_this, "")
        Next

        Return clean_string

    End Function

Private Function ConvertASCIIToHEX(ByVal StringText As String) As String

        Dim intStrLen As Integer
        Dim intLoop As Integer
        Dim strHex As String = ""

        StringText = Trim(StringText)
        intStrLen = Len(StringText)
        For intLoop = 1 To intStrLen
            strHex = strHex & " " & Right$("0" & Hex(Asc(Mid(StringText, intLoop, 1))), 2)
        Next
        ' need to reverse the string
        Dim str() As String = Split(Trim(strHex), " ")
        Array.Reverse(str)

        strHex = ""
        For Each s As String In str
            strHex += s
        Next
        Return strHex

    End Function

Public Function ConvertHEXToNumber(ByVal hexValue As String) As Object

        If Len(hexValue) = 1 Then Return 0

        Try
            Dim iInputIndex As Integer = 0
            Dim iOutputIndex As Integer = 0
            Dim hexLen As Integer = Len(hexValue) / 2 - 1
            Dim bArray(hexLen) As Byte

            For iInputIndex = 0 To hexValue.Length - 1 Step 2
                bArray(iOutputIndex) = Byte.Parse(hexValue.Chars(iInputIndex) & hexValue.Chars(iInputIndex + 1), Globalization.NumberStyles.HexNumber)
                iOutputIndex += 1
            Next

            Array.Reverse(bArray)
            Select Case hexLen
                Case 1,3
                    Return BitConverter.ToSingle(bArray, 0)
                Case 9
                    Return BitConverter.ToUInt64(bArray, 0)
            End Select

        Catch ex As Exception
            Throw New FormatException("The supplied hex value is either empty or in an incorrect format. Use the following format: 00000000", ex)
        End Try

    End Function

Open in new window

0
 
LVL 5

Accepted Solution

by:
Barsham earned 2000 total points
ID: 34181684
I was able to convert byte array to string by following code:
I think this is what you want my friend.
Please let me know if you have any question.

Dim bb As Byte() = New Byte() {78, 111, 115, 102, 101, 110, 116, 111, 114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        Dim strResult As String = New System.Text.UTF8Encoding().GetString(bb).Trim

Open in new window

0
 
LVL 1

Author Comment

by:sgaggerj
ID: 34184061
Yep! that was exactly what i needed!
then to do the opposite i'd do

dim bb(64) as byte
System.Text.UTF8Encoding().GetBytes("Nosfentora",0,len("Nosfentora"),bb,0)

correct?

(at least in my test that seemed to work.)
0
 
LVL 5

Expert Comment

by:Barsham
ID: 34184424
correct.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Make the most of your online learning experience.
If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Starting up a Project

927 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question