views:

190

answers:

6

Hi

I have a GSM date/time stamp from a PDU encoded SMS it is formatted as so

\x90,\x21,\x51,\x91,\x40,\x33

format yy,mm,dd,hh,mm,ss

I have read them from a binary file into a byte array. I want to convert them to a string but without doing any decoding I want to end up with a string that contains 902151914033. I then need to reverse each 2 characters in the string.

Can anyone give me some pointers? Many Thanks

A: 

What you mean is that you do want to do some processing! The unprocessed bytes are most easily represented as characters.

I think what you want is something along the lines of:

r = ''
for num in array:
    r += '%2X' % num
return r

Which I'm sure could be wrapped up in an anonymous function, if necessary.

Autopulated
@Autopulated: fixed your answer to the first question, `'\x90'` is `chr(0x90)` and not `chr(90)`. The LC solutions are better though.
RedGlyph
Ah, thanks, forgot it was hex :)
Autopulated
+3  A: 

This should get you started:

>>> s = b'\x90\x21\x51\x91\x40\x33'
>>> lst = [hex(z)[2:] for z in s]
>>> lst
['90', '21', '51', '91', '40', '33']

>>> string = ''.join(hex(z)[3:1:-1] for z in s)
>>> string
'091215190433'
Hamish Grubijan
+4  A: 

To convert to hex:

hexdata = ''.join('%02x' % ord(byte) for byte in bindata)

To reverse every other hex character (if I'm understanding correctly):

hexdata = ''.join(('%02x' % ord(byte))[::-1] for byte in bindata)

Out of Hanwell
Latest Python has a better (IMO) string formatting: http://www.python.org/dev/peps/pep-3101/
Hamish Grubijan
@lpthnc: matter of taste, really. Keep it as simple and as readable as possible :-)
RedGlyph
A: 

If, in your question, the string you have provided is the literal set of bytes (as ascii) including the \ and , and you wish to strip them out you could use the binascii module and str.replace:

import binascii
qp = binascii.b2a_qp( bunchabytes )
plainstring = qp.replace( '\\x', '' ).replace( ',', '' )

The resultant plainstring will consist of only the digits.

charstar
A: 

Many thanks for all your replies.

lpthnc's solution is exactly what I wanted. I ahve run into one more problem though.

If the bytearray contains b'\x00\x00\x00

the conversion will return only 000

the digits need to stay as 000000 because the 0000 could represent the time 00:00

Could I also ask someone to explain lpthnc's solution as I am having trouble working out exactly how it does the conversion?

Many thanks for your patience

honeyfuzz
A: 
switcher= dict(
    (n1*16 + n2, n2*16 + n1)
    for n1 in range(16)
    for n2 in range(16)
)

def nibble_switcher(bindata):
    return type(bindata)(switcher[i] for i in bindata)
    # will work with many types, not only bytearray

def nibble_switcher_as_hex_string(bindata):
    return ''.join("%02x" % i for i in nibble_switcher(bindata))
ΤΖΩΤΖΙΟΥ