manipulating hex values

Grant Edwards grante at visi.com
Tue Apr 1 14:25:11 EDT 2008


On 2008-04-01, Stephen Cattaneo <stephen.cattaneo at u4eatech.com> wrote:

> I am relatively new to socket programming.  I am attempting to
> use raw sockets to spoof my IP address.  From what I can tell
> I will have to build from the Ethernet layer on up.  This is
> fine, but I am having some trouble with manipulating my hex
> values. 
>
>  Seems to me that there are two ways to store hex values:
> 1. as literal hex - 0x55aa

That's a hex represenation of a literal integer object.  The
object itself isn't either decimal or hex.  It's and integer
object.  [It's _probably_ stored in binary, but that's beside
the point.]

> 2. as a string - "\x55aa"

That is the string "Uaa".  Perhaps you meant "\x55\xaa"?  If
so, that might or might not have the same bit-pattern as
0x55aa depending on what CPU you're using.

> If I want to convert hex to decimal I can use: int("\x55aa", 16)

No you can't'

 1) That call doesn't convert hex to decimal.  It converts to
    an integer object (which almost certainly is stored in 2's
    compliment binary).  There is nothing in decimal in the
    example.

 2) "\x55aa" doesn't mean what you think it does.  "\x55aa" is
     a three byte string consisting of a byte with the value
     0x55 and then two ascii 'a' bytes.  0x55 is an ascii 'U'.

     I think you meant "0x55aa".  That's completely different
     from either "\x55aa" or "\x55\xaa".
     
> # note that plain 0x55aa, instead of "\x55aa", will 
> raise an exception

That's because the above function call requires a string.
0x55aa isn't a string.  It's an integer literal.  "\x55aa" is a
three byte string that's equal to "Uaa", and it can't be
converted to an integer.

> The Question:
> If I want to do any kind of calculation I have found its best to just 
> convert my values to decimal, do the math, then convert back to hex.

First: stop talking (and thinking) about "decimal" stuff.
You're not really doing anything in decimal in any of the code
you've posted so far.

> In my bellow code I get
> """byteList.append(int(value,16))
> ValueError: invalid literal for int()"""
> when attempting to run.

No you don't.  You get this:

  Traceback (most recent call last):
    File "foo.py", line 20, in ?
      checksum = calcIPChecksum(["\x45" + "\x00", "\x01\x4a", "\x00\x00", "\x40"+"\x00", "\x20"+"\x11"])
  NameError: name 'calcIPChecksum' is not defined

Don't re-type examples in postings.  Paste in the actual code
that you're using.  That way we don't have to try to guess
about the differences between the real code and what's in the
posting.

> I do not understand why this exception is being raised?

If you want to understand why you're getting that exception,
add the line "print value" immediately prior to the
int(value,16) line.

> It is a for loop iterating over a list of hex strings.  Sorry
> for the long-ish question.  Any help or comments would be
> appreciated.
>
>
> ----my checksum---
> def calcIPCheckSum(ipHeaders):
>    byteList = []
>    # convert groups from hex to dec
>    for value in ipHeaders:
>      byteList.append(int(value,16))  # Exception raised here!
>       
>    # 1's compliment
>    for index in range(len(byteList)): 
>       byteList[index] = abs(byteList[index] - 65535)
>      
>    # add bytes together shifting the extra byte
>    total = 0
>    for value in byteList:
>       total = total + value
>       if total > 65535:
>          total = total - 65535
>         
>    return hex(total)
>
> checksum = calcIPChecksum(["\x45" + "\x00", "\x01\x4a", "\x00\x00", 
> "\x40"+"\x00", "\x20"+"\x11"])

You pretty much lost me on the above algorithm
(hex/decimal/string/integer mixups aside).

FWIW, here's an IP checksum routine:

def calcIPCheckSum(ipHeaders):
    total   = 0
    for w in ipHeaders:
        total += w
    carries = total >> 16  
    sum     =  (total + carries) & 0xffff
    return sum ^ 0xffff

print hex(calcIPCheckSum([0x0100,0xf203,0xf4f5,0xf6f7]))


A slightly more terse version:

import operator
def calcIPCheckSum(ipHeaders):
    total   = reduce(operator.add,ipHeaders)
    carries = total >> 16 
    return ((total + carries) ^ 0xffff) & 0xffff
    

-- 
Grant Edwards                   grante             Yow! ... he dominates the
                                  at               DECADENT SUBWAY SCENE.
                               visi.com            



More information about the Python-list mailing list