Sign in to follow this  
Followers 0
Falcone88

BinaryString

27 posts in this topic

Hi, I just got my new laptop and installed the latest version of AutoIt, and was puzzled to find that what I had working for my _OscarLib project didn't work anymore. I located the problem as being with my binary number conversion function, with the source being the removal of BinaryString (well, renaming to Binary). I checked the history and it says that they were rewritten and scripts will have to be changed...

How should I go about changing them to get the old functionality back? Thanks!

If it helps you, this was my _BinaryNumber() function:

Func _BinaryNumber($iNum, $iLength=2)       
    Local $ret="", $iOffset, $iVal
        
    
    
    if $iNum < 255 Then
        $ret = StringLeft( BinaryString(  $iNum  ), 1 ) 
    Else
        
        $iOffset = Floor( $iNum / 256 )
        $iVal = Mod( $iNum, 256 )
        
        $ret = BinaryString( Chr($iOffset) ) & BinaryString( chr($iVal) )
    EndIf
    
    
        
    if StringLen($ret) < $iLength Then 
        Do
            $ret =  BinaryString( Chr(0) ) & $ret 
            
        Until StringLen($ret) == $iLength
    EndIf
    
    
    return $ret 
EndFunc ;==>_BinaryNumber

My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites



Hi, I just got my new laptop and installed the latest version of AutoIt, and was puzzled to find that what I had working for my _OscarLib project didn't work anymore. I located the problem as being with my binary number conversion function, with the source being the removal of BinaryString (well, renaming to Binary). I checked the history and it says that they were rewritten and scripts will have to be changed...

How should I go about changing them to get the old functionality back? Thanks!

If it helps you, this was my _BinaryNumber() function:

Func _BinaryNumber($iNum, $iLength=2)       
    Local $ret="", $iOffset, $iVal
        
    
    
    if $iNum < 255 Then
        $ret = StringLeft( BinaryString(  $iNum  ), 1 ) 
    Else
        
        $iOffset = Floor( $iNum / 256 )
        $iVal = Mod( $iNum, 256 )
        
        $ret = BinaryString( Chr($iOffset) ) & BinaryString( chr($iVal) )
    EndIf
    
    
        
    if StringLen($ret) < $iLength Then 
        Do
            $ret =  BinaryString( Chr(0) ) & $ret 
            
        Until StringLen($ret) == $iLength
    EndIf
    
    
    return $ret 
EndFunc ;==>_BinaryNumber
Don't actually know but my guess is that BinaryString($val) is the same as

String(Binary($val))


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Don't actually know but my guess is that BinaryString($val) is the same as

String(Binary($val))

Unfortunately, that doesn't work :rolleyes: Thank you, though


My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

Unfortunately, that doesn't work :rolleyes: Thank you, though

Do you have an example Input/Output for > 255 and < 255?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

try this it should work use it inplace of the stringbinary.....

BinaryToString ( expression )

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Correct me if I'm wrong, and it's unclear to me what $iNum is (how big/small it can be, because if it's greater than 65536 that Floor&Mod funk would mess it up for sure), but basically what you're doing in your function is converting to hexadecimal.

So all you need is

Hex($iNum)

If you don't want it to be zero-padded, then

StringReplace(Hex($iNum, 8), "00", "")

If you want binary variant, then

Binary( "0x" & Hex($iNum, 8))

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

@Smoke:

Yes, I still have the original with old version of autoit on my old computer.

1024 = [EOT] (It's white letters on a black background... couldn't copy it)

256 = [sOH] (see above)

Numbers less than 256 don't show up in the console as raw, probably because they're padded with chr(0) at the beginning. But, if you run string() on it:

200 = 0x00C8

@vintorecavaj:

I tried already with BinaryToString and it didn't seem to work :rolleyes:

@Siao:

It is "basically" converting it to hex, but not really. What I'm doing is converting an integer to the a word or dword, for $iLength 2 and 4 respectively, to be sent over TCP. I will experiment with your suggestions, however.


My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

@Smoke:

Yes, I still have the original with old version of autoit on my old computer.

1024 = [EOT] (It's white letters on a black background... couldn't copy it)

256 = [sOH] (see above)

Numbers less than 256 don't show up in the console as raw, probably because they're padded with chr(0) at the beginning. But, if you run string() on it:

200 = 0x00C8

@vintorecavaj:

I tried already with BinaryToString and it didn't seem to work :rolleyes:

@Siao:

It is "basically" converting it to hex, but not really. What I'm doing is converting an integer to the a word or dword, for $iLength 2 and 4 respectively, to be sent over TCP. I will experiment with your suggestions, however.

Sorry I will try to work on it if no one else gets it I will try later gtg

Share this post


Link to post
Share on other sites

With some fiddling, numbers >= 255 seem to work alright:

Func _BinaryNumber($iNum, $iLength=2)       
    Local $ret="", $iOffset, $iVal
        
    if $iNum < 255 Then
        $ret = StringLeft( Binary(  $iNum  ), 1 ) 
    Else
        
        $iOffset = Floor( $iNum / 256 )
        $iVal = Mod( $iNum, 256 )
        
        $ret = Binary( Chr($iOffset) ) & Binary( chr($iVal) )
    EndIf   
        
    if StringLen($ret) < $iLength Then 
        ConsoleWrite("Foo")
        Do
            ConsoleWrite( BinaryLen($ret) & "="& $iLength & "," & String( StringReplace($ret, chr(0), "00")) & @LF )
            $ret =  ( Chr(0) ) & ($ret)
            
        Until StringLen($ret) >= $iLength
    Else
        return BinaryToString($ret)
    EndIf   
    
    return ($ret)
EndFunc ;==>_BinaryNumber

My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

This gave me the result you are talking about... but not sure that it's exactly what you are wanting, I think the extra loop to make the string 2 chars or greater is throwing me off:

Func _BinaryNumber($iNum, $iLen = 2)
    Local $iOffset, $iVal, $nReturn
    If $iNum >= 255 Then
        $iOffset = Floor($iNum / 256)
        $nReturn = Asc(BinaryToString($iOffset))
    Else
        $nReturn = Asc(BinaryToString($iNum))
    EndIf
    Return $nReturn
EndFunc


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Hm... doesn't seem to work for me....

The extra loop is to ensure that it's the appropriate length. The default of 2 works just fine without the loop, but sometimes I need a DWORD value, which would be length 4. For values that aren't large enough to take up all four spaces by themselves, you need to pad with null character.

If it helps, here is my decoding function which should still work just fine; it didn't use BinaryString:

Func _BinaryNumberDecode($iNum);, $iLength=2)       
    ; A shortcut! 
    if StringInStr(String($iNum), "0x") Then                
        $iNum = StringMid(String($iNum),3)
        return dec($iNum)
    EndIf
    
    $iOffset = 1
    While StringMid(String($iNum),$iOffset,2) == "00"; or StringMid(String($iNum),$iOffset,2) == "0x"
        $iOffset+=2
    WEnd
    $sTrim = StringMid($iNum, $iOffset)
;~  _DebugPrint("Trim: " & $sTrim)
    $iLength = StringLen( $sTrim )
    $iVal = 0
    
    for $i=1 to $iLength
        $iVal += Number( String( Asc( StringMid($sTrim,$i,1) ) ) ) * (16^ (2*($iLength-$i)))
    Next
    
    return $iVal
EndFunc ;==>_BinaryNumberDecode

My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

I may be just being silly here... but I'm curious...

Is there a reason you can't just use StringToBinary() to Send it, and BinaryToString() to convert on the other side?


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

A valid question, but yes there is a reason: I don't control the server. This code is part of my in-devlopment _OscarLib to communicate with AOL's Oscar servers.


My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

Sorry, but doesn't

Dec(Hex($iNum))

do exactly what your _BinaryNumberDecode($iNum) func does?


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Nope. It's a bit more complicated. The first digit is an offset, and if you don't take that into account you lose value. 256 becomes 0, for example.

Yes, it works for small numbers, but above that you get into problems


My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Perhaps a dev can explain what exactly changed between BinaryString() and Binary()?

EDIT: Decided to throw a quick for-loop together to illustrate how it SHOULD work:

loop:

for $num = 240 to 270
    $enc = _BinaryNumber($num, 4)
    $dec = _BinaryNumberDecode($enc)

    ConsoleWrite("("&$num&" -> "&$dec&") = " & String($enc) & @LF)

output:

(240 -> 240) = 0x000000F0
(241 -> 241) = 0x000000F1
(242 -> 242) = 0x000000F2
(243 -> 243) = 0x000000F3
(244 -> 244) = 0x000000F4
(245 -> 245) = 0x000000F5
(246 -> 246) = 0x000000F6
(247 -> 247) = 0x000000F7
(248 -> 248) = 0x000000F8
(249 -> 249) = 0x000000F9
(250 -> 250) = 0x000000FA
(251 -> 251) = 0x000000FB
(252 -> 252) = 0x000000FC
(253 -> 253) = 0x000000FD
(254 -> 254) = 0x000000FE
(255 -> 255) = 0x000000FF
(256 -> 256) = 0x00000100
(257 -> 257) = 0x00000101
(258 -> 258) = 0x00000102
(259 -> 259) = 0x00000103
(260 -> 260) = 0x00000104
(261 -> 261) = 0x00000105
(262 -> 262) = 0x00000106
(263 -> 263) = 0x00000107
(264 -> 264) = 0x00000108
(265 -> 265) = 0x00000109
(266 -> 266) = 0x0000010A
(267 -> 267) = 0x0000010B
(268 -> 268) = 0x0000010C
(269 -> 269) = 0x0000010D
(270 -> 270) = 0x0000010E

Without the String(), all of the values of $enc are unreachable, due to the null padding before it. Here's an example with $iLength of 2, instead of 4 as with the above code:

(240 -> 240) = (241 -> 241) = (242 -> 242) = (243 -> 243) = (244 -> 244) = (245 -> 245) = (246 -> 246) = (247 -> 247) = (248 -> 248) = (249 -> 249) = (250 -> 250) = (251 -> 251) = (252 -> 252) = (253 -> 253) = (254 -> 254) = (255 -> 255) = (256 -> 256) = (257 -> 257) = 
(258 -> 258) = 
(259 -> 259) = 
(260 -> 260) = 
(261 -> 261) = 
(262 -> 262) = 
(263 -> 263) = 
(264 -> 264) = 
(265 -> 265) =  
(266 -> 266) = 

(267 -> 267) = 
(268 -> 268) = 
(269 -> 269) = 
(270 -> 270) =

Note that the weird characters (if they show up) aren't what you see in SciTE...

Hope this helps

Edited by Falcone88

My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Nope. It's a bit more complicated.

That was a rhetorical question.

Plz explain how the following code does not equal to "how it SHOULD work":

for $num = 240 to 270
    $enc = _BinaryNumber($num, 8)
    $dec = _BinaryNumberDecode($enc, 8)
    ConsoleWrite("("&$num&" -> "&$dec&") = " & String($enc) & @LF)
next

Func _BinaryNumber($iNum, $iLen=8) ;8 for dword, 4 for word
    Return Binary("0x" & Hex($iNum, $iLen))
EndFunc

Func _BinaryNumberDecode($iNum, $iLen=8)
    Return Dec(Hex($iNum, $iLen)) ;8 for dword, 4 for word
EndFunc

(actually don't bother explaining, because I'm using rhetorics again)

If you want to read about BinaryString and Binary, see here

http://www.autoitscript.com/forum/index.php?showtopic=43881

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Thank you for the link, that's exactly what I was looking for.

Even if you wanted the explanation, I probably couldn't give it. But the fact remains that it doesn't work for this problem. Thank you, though.


My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

I have read this twice over and am still confused what you want... on your post where you said how it should work the output you made can be produced by-

for $num = 240 to 270
    ConsoleWrite("(" & $num & " -> " & $num & ") = " & "0x" & Hex($num) & @LF)
Next

but i dont think that's what you want... i seems your looking for a funtion that takes a number in decimal form and does somthing...if that's the case tell me what t would give for thees numbers-

1

32

128

270

1024

5000

Or if that's not the case at all tell me like 4 sample inputs and what thier respective outputs should be.

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

Without couching it with String(), you can't see the value of _BinaryNumber() for 1, 32, and 128. It has chr(0) before it.

270 = [sOH][sO] (Those are just 1 char each, but I can't copy them properly)

1024 = [EOT]

5000 = [DC3]^

What I'm trying to do is get the raw bytes from a string or integer. In Java, you could just do stream.print( number.getBytes() ); but nothing like that exists in Autoit -- hence my rediculous _BinaryNumber() function. As I explained, it used to work great with the old implementation of BinaryString(), but now in the newer version of Autoit, it's broken :rolleyes:

(PS: The arrow thing was just me testing to make sure it gets decoded properly; I know the decode works)

EDIT:

Food for thought: Using this as a replacement for BinaryString, it *looks* the same as in the old version, but it is apparently not understood by Oscar. I guess it doesn't convert to Binary/byte type properly...

Func BinaryString ($sData)  
    ;return Binary( ($sData) )
    Local $b = Binary($sData)
    Local $out = ""
    
    for $i=1 to BinaryLen($B)
        $out &= Chr( BinaryMid($b, $i, 1) )
    Next
    
    return ($out)
EndFunc
Edited by Falcone88

My Code:- _TocLib - UDF for TOC protocol (The simplified one used by 3rd party AIM/ICQ clients)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0