B4J Question Binary String to Hex

paddy12309

Member
Licensed User
Hi everyone,

hoping i can get some advice, I have a String (which is binary) but need a hex number is there any nice way of doing this?

binary is off unknown length... but minimum 8

cheers
Paddy
 

paddy12309

Member
Licensed User
Binary 1000000000000000000000000000000000000000000000000000
hex 8000000000000

The caveat to this is the binary will be at least 8 bits but up to an unknown length....
 

amykonio

Member
Licensed User
This binary string will always contain a positive number or it can contain also a negative? It will be of a defined length (and zero filled if necessary)? How this binary number was created?
 

paddy12309

Member
Licensed User
hi, yep it will always be 0 or positive! its created by string concatination on if statements
B4X:
Sub AlarmActive (AlMask As String)
    If Not(Main.sql1.IsInitialized) Then
        Log("SQL1 Failed")
        Return
    End If
    Dim AlMask As String 
    AlMask = "00000000"
'    Dim count As Int
'    count = 0
    Dim RS As ResultSet = Main.sql1.ExecQuery("SELECT * FROM DeviceStatus INNER JOIN DeviceLive ON DeviceStatus.DeviceSN = DeviceLive.DeviceSN ")
    Do While RS.NextRow
        Log("DevSN; " & RS.GetInt("DeviceSN") &  "   EmStat; " & RS.GetInt("EmStatus"))
        If RS.GetInt("EmStatus")  < "4" Then
            AlMask = AlMask & "0000"
        Else If RS.GetInt("EmStatus") = "4" Then
            AlMask = AlMask & "0001"
        Else If RS.GetInt("EmStatus") = "5" Then
            AlMask = AlMask & "0010"
        Else If RS.GetInt("EmStatus") = "6" Then
            AlMask = AlMask & "0100"
        Else if RS.GetInt("EmStatus") = "7" Then
            AlMask = AlMask & "1000"
        Else
            Log("error")
            Log(RS.GetInt("EmStatus"))
        End If
    Loop
        'Log(AlMask)
       
       
       
'    Dim byteAl() As Byte = AlMask.GetBytes("UTF8") 'convert to bytes
'    Log(BytesToString(byteAl, 0, byteAl.Length, "UTF8")) 'convert to string
'    Dim b(1) As Byte
'    Dim msg As String
'    For i = 0 To byteAl.Length - 1
'        b(0) = byteAl(i)
'        msg = conv.HexFromBytes(b)
'        Log(msg)
'    Next
'       
'       
       
       
        Return  AlMask
End Sub
however it will not be a defined length, and will often return something like; 0001000000000000000100000000
 

DonManfred

Expert
Licensed User
something like; 0001000000000000000100000000
NEVER!
Based on
Dim AlMask As String
AlMask =
"00000000"
The string will start with eight zeros PLUS four digits.
"00000000" + "0001" for ex.

So it will start with "000000000001" and it returns something like
00000000000110000010 is made of "00000000"+"0001"+"1000"+"0010" in case of 3 results from the database.
 
Last edited:

amykonio

Member
Licensed User
So the length will always be a divided by 4 (to check if we have a valid string)? And you need to convert the string to a hex for each set of 4 bits or for the full length of bits (I guess it will be the second)...
 

Erel

Administrator
Staff member
Licensed User
Not tested too much:
B4X:
Sub BinaryToHex (Binary As String) As String
   Do While Binary.Length Mod 4 <> 0
       Binary = "0" & Binary
   Loop
   Dim res As StringBuilder
   res.Initialize
   For i = 0 To Binary.Length - 1 Step 4
       res.Append(Bit.ToHexString(Bit.And(0xf, Bit.ParseInt(Binary.SubString2(i, i + 4), 2))))
   Next
   Return res.ToString
End Sub
 

paddy12309

Member
Licensed User
hah yes good point Don! So the total needs to be converted to hex!, sorry i should of been clearer on this!
 

emexes

Well-Known Member
Licensed User
created by string concatenation on if statements
B4X:
...
If RS.GetInt("EmStatus")  < "4" Then
    AlMask = AlMask & "0000"
Else If RS.GetInt("EmStatus") = "4" Then
    AlMask = AlMask & "0001"
Else If RS.GetInt("EmStatus") = "5" Then
    AlMask = AlMask & "0010"
Else If RS.GetInt("EmStatus") = "6" Then
    AlMask = AlMask & "0100"
Else if RS.GetInt("EmStatus") = "7" Then
    AlMask = AlMask & "1000"
Else
...
Is there some reason for binary?

Why not just send the values directly, eg: 0, 1, 2 , 4 or 8?

The repeated calls to RS.GetInt("EmStatus") are mildly painful, too. Is there a reason it can't be done just once, and the result held in a temporary Int? And then compared to Int rather than String literals.

The AlMask parameter seems to be unused. And whilst Subs have a default return type of String, which happily matches what you are returning... it might be better to codify this so that there is no ambiguity, eg:
B4X:
Sub AlarmActive () As String
(assuming the AlMask parameter is not needed)
 
Last edited:

paddy12309

Member
Licensed User
Thankyou @emexes for the recommendation of setting the sub to return string. The reason for the binary is I'm interfacing with a system that assigns lines in a specific way for example the first digit in the binary represents line 1, the second line 2 the third line 3 and so on. Annoyingly because of this I need all the 0s as they are, the final binary then needs to be converted as a whole to hex. Sadly i have no ability to change the way i get to interface with this device, hence the strange binary hex combo!
 

paddy12309

Member
Licensed User
Sorry to be a pain guys, I'm still floundering here, with a string of binary e.g. 000000000000000000000010000000000000000000000000 I need to convert the whole thing to hex e.g. 2000000 I've used @Erel 's code further up but get 2000000 instead from my binary string? I might be being very thick here but does that step through and convert each 4 digits or the whole string?
 

paddy12309

Member
Licensed User
So using the code snippet you kindly provided I successfully turned my string into hex however it was 2 decimal places out? 2000000 instead of 200000000.
I was wandering whether this is as it converts each block of 4 digits as opposed to the string as a whole? if so how would I change it?

Cheers Paddy
 

Daestrum

Well-Known Member
Licensed User
If you want it to treat it as 2000000 hex you need to prepend 0x to the string.
ie, 0x2000000

If you use the string without the 0x it will assume its an int
 

emexes

Well-Known Member
Licensed User
with a string of binary e.g. 000000000000000000000010000000000000000000000000 I need to convert the whole thing to hex e.g. 2000000 I've used @Erel 's code further up but get 2000000 instead from my binary string?
You are expecting e.g. 2000000 but you get 2000000 instead??? I am with Erel on this, ie: those numbers are the same, so we don't understand the problem.

does that step through and convert each 4 digits or the whole string?
Yes.

If we put commas in to group the digits, similar to grouping decimal digits by 1,000s (working left, from the right end... not that it matters here, since the number of digits is a multiple of 4 anyway):
B4X:
binary: 0000,0000,0000,0000,0000,0010,0000,0000,0000,0000,0000,0000
hex:       0    0    0    0    0    2    0    0    0    0    0    0  ie 2000000
 
Top