Search code examples
pythonpython-2.7bitwise-operatorsxor

Python code to extract last 16 characters from 32 characters


I am trying to extract the last 16 characters of this hexadecimal value and xor it with the first 16 bits of the same 32 characters or 128-bit value using python code. I am not sure what function to be used here. I tried taking this as a string divide the length by half and then xor the two values. Is there a possibly easy way to find the extract these bits and xor them?

For instance my 32 bit value is : ee230c06cac0aa070be45290b1cb11ee

My last 16 bit value should be : 0be45290b1cb11ee; and
my first 16 bit value should be: ee230c06cac0aa07


Solution

  • Note: based on your example you work with a 128-bit number, and you want to split it into two 64-bit numbers. The below stated techniques can however easily be modified for any number of bits.

    In order to obtain the lowest 16 bits, you can mask with 0xffff, like:

    lowest_16 = number & 0xffff

    Now in order to get the highest 16 bits, you can shift (and probably better mask as well, since in numbers have arbitrary length):

    highest_16 = (number  >> 16 ) & 0xffff
    #                     ^       ^ masking out higher bits
    #                     | bitwise shift 16 position to the right

    So the result is:

    result = ((number >> 16 ) & 0xffff) ^ (number & 0xffff)
    #                                   ^ bitwise xor operation

    Note that you can mask after the xor (saving one bitwise and operation) since by masking, you set these higher values to zero anyway. So you can make it more efficient like:

    result = ( (number >> 16 ) ^ number) & 0xffff

    In case you want to work with 128-bit numbers, you can use:

    result_128 = ( (number >> 64 ) ^ number) & 0xffffffffffffffff
    #                                          ^ 64-bit mask

    For example:

    >>> number = 0xee230c06cac0aa070be45290b1cb11ee
    >>> hex(( (number >> 64 ) ^ number) & 0xffffffffffffffff) # xor-ing
    '0xe5c75e967b0bbbe9'
    >>> hex(number >> 64) # highest bits
    '0xee230c06cac0aa07'
    >>> hex(number & 0xffffffffffffffff) # lowest bits
    '0xbe45290b1cb11ee'