Need Tcl help: Convert to ulong

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Need Tcl help: Convert to ulong

  • Creator
    Topic
  • #48516
    Rentian Huang
    Participant

      I have a C function that generates a key, and needs to be converted into a Tcl function:

      Code:

      void sum_add(ulong*sum, const char* str)
      {
       size_t len = strlen(str);
       for (size_t i=0; i


      This is what I did:

      Code:

      proc sum_add {sum str} {
      set len [string length $str]
      for {set i 0} {$i < $len} {incr i} { set sum 0 set sum [expr ($sum + ([scan [string index $str $i] %c] * (($i + 1) << 4))) % 0x10000] } return $sum }


      ulong is a 32-bit unsigned integer

      The correct result is: [sum_add 0 “Dr.X”] = 0x00003120

      But I got [sum_add 0 “Dr.X”] = 5632

      Why? I guess the scan has problem but I don’t know how to fix it.

      Can anyone help? Thanks!

      Sam   8)

    Viewing 3 reply threads
    • Author
      Replies
      • #58827
        John Mercogliano
        Participant

          Rentian,

            You’re going to kick yourself but the first thing you need to do is move the set sum 0 outside of the for loop.  That will fix it so that it will return the correct integer value. Expr always returns a numeric result so something like expr 0x21 * 0x02 returns 66 instead of 0x42. You will need to use the format command to return a Hex string as so:

          set sum [format 0x%08x [expr ($sum + ([scan [string index $str $i] %c] * (($i + 1) << 4))) % 0x10000]]

          John Mercogliano
          Sentara Healthcare
          Hampton Roads, VA

        • #58828
          Rentian Huang
          Participant

            John, you are absolutely right, I was being stupid putting that [set sum 0] in the loop, and your format 0x%08x works fine too.

            But somehow I just can not get the correct result. I changed my code as below:

            Code:

            proc sum_add {sum str} {
            set len [string length $str]
            for {set i 0} {$i < $len} {incr i} { set char [string index $str $i] if { ![string is integer $char] } { set char [scan $char %c] } set sum [format 0x%08x [expr ($sum + ($char * (($i + 1) << 4))) % 0x10000]] } return $sum }

            This is the calls:

            Code:

            set sum 0
            set sum [sum_add $sum “”]
            set sum [sum_add $sum “”]
            set sum [sum_add $sum “Dr.X”]
            echo sum_char<$sum>
            set sum [sum_add $sum 1065507963]
            echo sum_num<$sum>

            This is the output:

            Code:

            sum_char<0x00003120>
            sum_num<0x000041f0>

            And according to our vendor, the first one is correct, but the 2nd has problem:

            Code:

            sum in 1st step: 0x00003120
            sum in 2nd step: 0x0000e6f0

            Thanks for any more help, I have been struggling for this for a while   😥

            Sam

          • #58829
            John Mercogliano
            Participant

              Code:


              proc sum_add {sum str} {
                set len [string length $str]
                for {set i 0} {$i < $len} {incr i} {      set char [string index $str $i]      set char [scan $char %c]      set sum [format 0x%08x [expr ($sum + ($char * (($i + 1) << 4))) % 0x10000]]   }   return $sum }

              Notice I removed the if statement? Did you try it this way?  Looking at your C code, the if logic is not needed as even if the string contains a number the C code was still using the ascii equivalent in its calculations not the actual number.  So for example “1065507963”, char would be equal to 42 not 1, 48 not 0…etc

              Hope this helps.

              John Mercogliano
              Sentara Healthcare
              Hampton Roads, VA

            • #58830
              Rentian Huang
              Participant

                That works like magic, John, thanks so much for the help, I really appreciate it!!!

                Sam  ðŸ˜€

            Viewing 3 reply threads
            • The forum ‘Cloverleaf’ is closed to new topics and replies.