Irios

Any clever way to convert hex to uint64 (and beyond)? (Any UDF that does it?) [SOLVED]

11 posts in this topic

#1 ·  Posted (edited)

Searching and searching but I'm unable to find anyone with a proper solution. I see a lot of similar questions on this topic, but nothing that really provides what I'm looking for.

Basically, I just want to convert a 8 byte hex value to unsigned integer. I.e. "FFFFFFFFFFFFFFFF". I'm working on SNMP opaque data types, and UINT64 values end up as signed INT64 when I use the internal processing of AutoIt. (Yeah, I know, this is because AutoIt always uses signed)

 

Example ( I know you guys love example code snippets haha, so here's a two-liner):

 

$sUINT64 = "FFFFFFFFFFFFFFFF"

ConsoleWrite( Dec($sUINT64) )

-1 is not the result I want, of course.

 

And I don't want "1.84467440737096e+019" either by adding manually in AutoIt. I need the decimal value (as a string) of 264 = 18,446,744,073,709,551,616

 

Anyone got a clever UDF for this? Or will I have to write one myself, adding and multiplying each hex value, and generating a text string as a result? :) I know how it can be done, I just hoped someone already had done it so I could steal their code. :D

 

Edited by Irios
solved!

Share this post


Link to post
Share on other sites



You could try the BigNum UDF

 

1 person likes this

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Local $aResult = DllCall("msvcrt.dll", "INT:cdecl", "sprintf", "STR", "", "STR", "%llu", "UINT64", -1)

ConsoleWrite($aResult[1] & @CRLF)

;~ 18446744073709551615

 

Edited by Tekk
I like to edit posts
1 person likes this

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thank you both :)

 

EDIT: Again, thanks @Tekk. It was horribly difficult to search for these things without really knowing what to look for. But with the DllCall example, it opened a whole new world to me, as I never realized you could do it that way. I even found ways to convert int to float now, and int64 to double. (

)

Edited by Irios

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

A little trick I discovered. I think the fastest way to convert Int64 to double is to concatenate and execute.

$iInt = 12345678901234567
$fFloat = Execute($iInt & '.0')
MsgBox(0, "", $fFloat)


Edit: Hmm division by 1 should be faster.

$iInt = 12345678901234567
MsgBox(0, "", $iInt/1)

 

Edited by czardas

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

18 minutes ago, czardas said:

Hmm division by 1 should be faster

Hmmm, multiplication by 1.0 should be faster than division (in FPU assembly at least).^_^

$iInt = 12345678901234567
MsgBox(0, "", $iInt*1.0)

 

Edited by RTFC
1 person likes this

Share this post


Link to post
Share on other sites

Interesting thing is that AutoIt returns always an signed value. Is this a bug?

 

Global $s1 = "FFFFFFFFFFFFFFFF"
Global $s2 = "FFFFFFFFFFFFFFF0"

ConsoleWrite(_HexString2Uint64($s1) & @CRLF)
ConsoleWrite(_HexString2Uint64($s2) & @CRLF)

Func _HexString2Uint64($sHex)
    Local $b = Binary("0x" & $sHex)
    Local $tStruct =  DllStructCreate("UINT64")
    Local $tStruct2 = DllStructCreate("byte[8]", DllStructGetPtr($tStruct))
    DllStructSetData($tStruct2, 1, $b)
    Return DllStructGetData($tStruct, 1)
EndFunc

 


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

@RTFC Now I know why I went the root I did. Compare:

MsgBox(0, "", '123456789012345678901234567890'*1.0)
MsgBox(0, "", Execute('123456789012345678901234567890' & '.0'))

The second method works for a few hundred digits and the first method quickly hits a brick wall.

Edited by czardas

Share this post


Link to post
Share on other sites

Compare like with like:

MsgBox(0, "", '123456789012345678901234567890.0'*1.0)
MsgBox(0, "", Execute('123456789012345678901234567890' & '.0'))

 

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

On 29/09/2016 at 0:27 PM, funkey said:

Interesting thing is that AutoIt returns always an signed value. Is this a bug?

No, it's not a bug. AutoIt always uses signed int 64. That's what my original post was about: how to get around this limitation.

I could not figure out a way to use DllCall, DllStructCreate, DllStructSetData, DllStructGetData. All the solutions/examples I found uses integers as paramteres, and won't work because AutoIt uses signed integers.

Maybe someone has a way to do it?

 

This is the solution I ended up using in my script as of today... Not very elegant, but it works. Can easily be extended beyond 64 bit if you need to.

; v1.0  2016.09.29  Handles hex strings up to 16 characters in length i.e. "FFFFFFFFFFFFFFFF". Outputs a string representing the integer.
; Example: HexToUnsigned64("FFFFFFFFFFFFFFFF")
Func HexToUnsigned64($_HexString)   
    
    ; quick check to make sure it's a string, and 16 characters or shorter
    If (VarGetType($_HexString)<>"String") Or (StringLen($_HexString)>16) Then Return -1        

    ; Check to see if the value is within signed 64 bit. If so we just return the value immediately... 
    ; We pad with zeros to get the correct length of 8 bytes (total 16 characters). 
    ; Then we check to see if the the value is higher than 7FFFFFFFFFFFFFFFh (max positive value for signed 64 bit)
    If (StringLen($_HexString)<=16) Then                                    
        $_HexString = StringFormat("%016s", $_HexString)                    
        If (Dec(StringLeft($_HexString,1))<8) Then Return Dec($_HexString)
    EndIf

    ; this is value of the leftmost 64th bit in an unsigned int 64. It must be a string, of course,
    ; as AutoIt only uses signed 64 bit integers.
    Local Const $_UINT64 = "9223372036854775808"        

    ; we remove the highest bit so we can convert the other 63 bits internally
    $_iTmp = Dec(StringLeft($_HexString,1)) - 8         
    
    ; build a new 63bit integer string (without the highest bit)
    $_HexString = $_iTmp & StringRight($_HexString,15)  
    $_HexString = String(Dec($_HexString))
    
    ; padding input string with zeros so both become the same length (19 digits)
    $_HexString = StringFormat("%019s", $_HexString)    

    Local $co = 0, $addReturn = ""
    ; starting at the far right side, max ops is 19 digits (number of digits in $_UINT64)
    For $A = 19  To 1 Step -1                                                                                   
        ; building the return string, from the right-most side
        $addReturn = Mod( ( StringMid($_UINT64,$A,1) + StringMid($_HexString,$A,1) + $co), 10) & $addReturn     
        ; getting the carry-over for the next loop
        $co = Int(( StringMid($_UINT64,$A,1) + StringMid($_HexString,$A,1) + $co ) / 10)                        
    Next

    If $co = 0 Then $co = ""
    Return $co & $addReturn ; all done, and returns the final value as a string

EndFunc

 

Example use:

$sResult = HexToUnsigned64("FFFFFFFFFFFFFFFF")
ConsoleWrite($sResult & @CRLF)

...the output is "18446744073709551615"

 

Edited by Irios
words and letters

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

  • Similar Content

    • paullauze
      ERROR: undefined macro. If @OSArch =
      By paullauze
      i just got a new windows 7 64 bit machine at work. I get a error when complilling with #include <AD.au3>
       
      excerpt from console:
      xxxAuto ItIncludeAD.au3(423,15) : ERROR: undefined macro.
         If @OSArch =
         ~~~~~~~~~~~^
      xxxAuto ItIncludeAD.au3(423,35) : ERROR: undefined macro.
         If @OSArch = "IA64" Or @OSArch =
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
      xxxAuto ItIncludeAD.au3(1290,66) : ERROR: _ArrayToString() called with wrong number of args.
           $aAD_Objects[$iCount2][$iCount1 - 1] = _ArrayToString($aTemp)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
      C:\Program Files (x86)\AutoIt3\Include\Array.au3(808,87) : REF: definition of _ArrayToString().
      Func _ArrayToString(Const ByRef $avArray, $sDelim, $iStart = Default, $iEnd = Default)
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
      xxxAuto ItIncludeAD.au3(1306,51) : ERROR: _ArrayToString() called with wrong number of args.
          $aAD_Objects[$iCount2] = _ArrayToString($aTemp)
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
       
      even if all i am compiling is th eincludes
      #include <Word.au3>
      #include <Excel.au3>
      #include <AD.au3>
       
      it has always worked fine XP, so this must have something to do with window 7 or being 64 bit.
    • ColinRH
      32 bit and 64 build problem
      By ColinRH
      I'm having a problem creating a 64 bit exe using Aut2Exe. I'm running on a Windows 7 64 bit PC and OS.
      If I compile my test script using a right click on the test script I can successfully create a 32 bit or a 64 bit exe. I can easily check this by looking at the properties of the exe, compatibility settings where, for the 64 bit exe compatibility settings "below" Vista are not available whereas, for the 32 bit exe they are.
      If I compile using Aut2Exe (running it from a non-compiled au3 script) then, using the method above, both the 32 bit and 64 bit builds appear to actually be 32 bit exes. The file, MakeTest.au3 is attached.

      MakeTest.au3

      If I try to do the same build using the command line input for Aut2Exe I can build the 32 bit version OK but the 64 bit build returns the error "Unable to read in AutoIt stub file. (AutoItSC.bin)". Surely it should be looking for AutItSC_x64.bin if I use the /x64 switch shouldn't it?

      If I try to run Aut2exe_x64 from the command line I get the "not recognised as an internal or external command" message.

      However, double clicking on Aut2exe_x64 and using the UI that's displayed I do get a 64 bit version built.

      I'm very confused - I really need to use a script to compile both 32 and 64 bit versions as the whole thing is part of an automatically built installation "application". Can anyone make sense of it for me or ami I just being stupid?
    • Aipion
      AXml v1.0 - A fast Xml parser with DOM interface.
      By Aipion
      This is a Wrapper for Pugixml, made with C++ by me and uses the version 1.2.

      Description
      pugixml is a light-weight C++ XML processing library. It consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer. pugixml enables very fast, convenient and memory-efficient XML document processing. However, since pugixml has a DOM parser, it can't process XML documents that do not fit in memory; also the parser is a non-validating one, so if you need DTD or XML Schema validation, the library is not for you.


      License
      The Xml parser(Pugixml) is distributed under the MIT license:



      This means that you can freely use pugixml in your applications, both open-source and proprietary.

      Features
      Load/save XML files to an in-memory document object model (DOM). Add name/value attribtes to nodes. Numerous methods for iterating over the nodes in a document. Built in XPath. Full Unicode support. MsXml Independent. Has about 47 Functions.Works on: Microsoft Windows 2000, XP, Server 2003, Vista, 7, Server 2008. 32 bit



      ____________________________________________________________________________________________

      Not supported any more due the fact that I had a hard drive failure therefore lost the source code of the DLL.
      ____________________________________________________________________________________________

      Download Link
      AXml.zip
      Note: I have also included a 64bit DLL but as I don't have a 64bit computer it remains untested.