3

My python script gets and sends words over a serial line. Each word is a signed 24-bit value, received as hex string. The script should now take these strings and convert them to integers, do some calculations on it, and send them back in the same format. My problem is, how to do this conversion

Examples

Rx string -> calc int
 012345   ->  74565
 fedcba   -> -74566

calc int -> Tx string
  74565  -> 012345
 -74566  -> fedcba

How can this be done?

guo
  • 195
  • 1
  • 2
  • 12
  • Please confirm: the serial data is six bytes of `'0'`-padded text in the range `0-9a-fA-F`. It is not 3-bytes of binary data. Is that correct? – Robᵩ Oct 09 '14 at 16:19
  • Can your **Task Definition** also explicitly confirm any form of a lower-level serial line-code protocol present ( data-bits, stop-bits, parity, CRC, framing, HDB3-transmission-line-code-protection et al)? – user3666197 Oct 09 '14 at 16:26
  • 2
    @user3666197: there is another part of the software which treats the low level stuff, my part only gets/sets the 6 char string – guo Oct 10 '14 at 06:19
  • "*there is another part of the software which treats the low level stuff*" - that makes much more sense. It seemed unlikely that hardware guys would design a serial line protocol like you described. – Robᵩ Oct 10 '14 at 12:55

3 Answers3

5
def str_to_int(s):
    i = int(s, 16)
    if i >= 2**23:
        i -= 2**24
    return i

def int_to_str(i):
    return '%06x'%((i+2**24)%2**24)

Test results:

In [36]: str_to_int('012345')
Out[36]: 74565

In [37]: str_to_int('fedcba')
Out[37]: -74566

In [38]: int_to_str(74565)
Out[38]: '012345'

In [39]: int_to_str(-74566)
Out[39]: 'fedcba'

Reference: Hex string to signed int in Python 3.2?

Community
  • 1
  • 1
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • 1
    Could you explain why you perform the subtractions? Is that simply to make use of the negative ints as well? – lucidbrot Jul 31 '19 at 10:08
2

(Edit: An oversight on my part. See Rob's answer for correctly covering the negative sign numbers)

If you just want to convert a hex string into an int, do e.g.:

>>> int('0xff', 16)
255
>>> int('0xdaad', 16)
55981

The reverse can be done with the hex() function. From the help page:

Help on built-in function hex in module builtins:

>>> help(hex)
hex(...)
    hex(number) -> string

    Return the hexadecimal representation of an integer.

       >>> hex(3735928559)
       '0xdeadbeef'

It should be trivial to remove or add the '0x' if it's missing in your data stream. Here's an example to ensure padding to 6 chars (representing 3 bytes = 24 bits):

>>> '0x' + hex(255)[2:].rjust(6, '0')
'0x0000ff'

If you get the data in 3 byte form (24 bits), you can use int.to_bytes() and int.from_bytes() as described in the Python docs. This is new in Python 3.2.

Community
  • 1
  • 1
cfi
  • 10,915
  • 8
  • 57
  • 103
1
$ pip install bitstring

Then:

from bitstring import BitStream
s1 = BitStream('0x012345')
s1.int # 74565
s2 = BitStream(int=-74565, length=24)
s2.hex # fedcbb
Darko P.
  • 567
  • 1
  • 4
  • 14
  • I marked the answer of @Robᵩ, because his solution does not need installing a module. – guo Oct 10 '14 at 06:39