0

I have two hex values (provided as strings):

00000000fe000000 <- high order 32-bits

000000000001009f <- low order 32-bits

They need to be combined into a single value, and ideally - conveniently addressed like value[0:15] (returning bits 0 to 15, right to left).

What is the best way to do this in Python?

Community
  • 1
  • 1
tonysepia
  • 3,340
  • 3
  • 27
  • 45
  • are those ints or strings or binary strings? – Patrick Artner May 21 '18 at 14:39
  • They are hex values (not ints, I guess, as they have characters e and f) – tonysepia May 21 '18 at 14:41
  • oh, they are supplied (!) as strings! I misunderstood your question,sorry! – tonysepia May 21 '18 at 14:42
  • What does "combined into a single value" mean, exactly? There's an infinite number of ways to combine two things, like addition and multiplication and concatenation and whatnot. – Aran-Fey May 21 '18 at 14:43
  • @Aran-Fey, the combined result will be a binary value, with 64 ones and zeroes. First value is high-order bits, and the second one is low-order bits. – tonysepia May 21 '18 at 14:45
  • @Aran-Fey https://chortle.ccsu.edu/java5/Notes/chap85/ch85_12.html – tonysepia May 21 '18 at 14:46
  • In your example, the most-significant 8 bytes of both values are 0, and the least signficant 8 bytes are non-zero. How do you define low-order and high-order bits/bytes of these 16 bytes? (Which would be 128 bits, not the 64 from your comment above...) – Tom Dalton May 21 '18 at 14:50
  • @TomDalton. I don't understand this part, sorry: " the most-significant 8 bytes of both values are 0". 8 bytes = 64 bits. Each value in my example is 32 bits. What are you referring to? – tonysepia May 21 '18 at 14:54
  • Sorry, my comment isn't accurate and is def confusing. It should say: "In your example, the most-significant *4* bytes of both values are 0, and the least signficant *4* bytes are non-zero. How do you define low-order and high-order bits/bytes of these 8 bytes? – Tom Dalton May 21 '18 at 14:58
  • @TomDalton. No worries! I know that one of them is low- and high- because these are specific registers in the CPU. Basically, one register will always hold the low-part of the value and the other is always the high-part. – tonysepia May 21 '18 at 14:59
  • *Penny drops*. So in the example above, you want to end up with `0x00000000fe000000000000000001009f`? I think were were confused about how you wanted to combine these. The answer below looks right to me. – Tom Dalton May 21 '18 at 15:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/171479/discussion-between-tony-sepia-and-tom-dalton). – tonysepia May 21 '18 at 15:48

1 Answers1

1

With two ints, you simply use bit-shifting and |:

high = 0x00000000fe000000
low = 0x000000000001009f

result = (high << 32) | low

For any other input, I suggest converting them to ints first, and converting the result back to whatever form you want.

To retrieve the original pieces, use bit-shifting in reverse

high = result >> 32

and & with an appropriate mask:

low = result & 0xffffffff
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you! The bit-shift makes total sense, and bitwise OR also makes sense. Could you please give an example of how to address parts of the resulting binary value (i.e. get part [15:0], where 0 is the rightmost bit and 15 is 15th from the right)? – tonysepia May 21 '18 at 15:54
  • @TonySepia search SO: [python int to binary+](https://stackoverflow.com/questions/699866/python-int-to-binary) you format it as string, then you can slice to string to your hearts content (or index into it). – Patrick Artner May 21 '18 at 16:41
  • tried it, but the endianness is wrong for approaching this task directly. I am looking for a clever way to do it, as @chepner clearly understands binary operations! – tonysepia May 21 '18 at 16:52
  • Possibly - reverse the string and then use indexing as I normally would – tonysepia May 21 '18 at 17:03