Reputation: 11
I'm using python v3.10.4. I'm trying build an array comprised of printable and non-printable chars and failing miserably. I've searched through Stackoverflow, I have multiple browser tabs open with python docs, and an O'Reilly Python pocket reference. And I still can't figure out how to do it.
I'm trying to make a function that takes a string argument that contains printable ascii chars. The function is suppose to format that string into a message packet by wrapping it with non-printable chars:
Format: <STX><ADDR><1-20 ASCII Chars><ETX><Checksum>
stx = b'\x02'
etx = b'\x03'
adr = b'A'
def format_msg(m):
count = len(m) + 4
msg = bytearray(count)
msg[0] = stx # Doesn't work.
msg[0] = b'\x02' # Doesn't work.
msg[0] = int('00000010', 2) # No errors, but wrong value is displayed.
msg[1] = b'A' # Doesn't work. Assigning a byte to a byte doesn't work?
msg[1] = 'A' # Doesn't work
msg[1] = int(b'A') # Doesn't work
msg[1] = ord('A') # No errors, but wrong value is displayed
msg[2:2]= bytearray(m,"ascii")
msg[len(m)+2] = int('00000011', 2) #etx Doesn't work like above.
# Calculate checksum
cs = 0
i = 0
while i < count-1):
cs ^= msg[i]
i+=1
print(msg)
msg[count-1] = cs
return msg
cmd_ba = format_msg("00")
print(list(cmd_ba))
This works, but is impractical, plus I can't figure out how to add a checksum to the end of cmd_ba.
cmd_ba = stx + bytes('A00',"ascii") + etx
print(list(cmd_ba))
cs = cmd_ba[0] ^ cmd_ba[1] ^ cmd_ba[2] ^ cmd_ba[3] ^ cmd_ba[4]
cmd_ba.append(cs) <-- Error: No 'append' attribute.
Output:
bytearray(b'00\x00\x00\x11\x00') <-- This is incorrect
[48,48,0,0,17,17] <-- This is incorrect
[2,65,48,48,3] <-- This is correct, but it's missing the checksum. The checksum would be 64 (@).
Update:
There are a couple of errors I discovered in my original post. The int object should have number base of 2 not 16. And "msg[:2]" should be "msg[2:2]", I think. I say that because, after the change I get the 2-chars of 'm' into msg at the right location, but the length of msg changes from 6 to 8.
With these changes the final print statement output is:
[2,65,48,48,3,64,0,0]
The trailing two zeros should not be there.
Upvotes: 0
Views: 608
Reputation: 2013
From this question, looks like you're appending bytes in the wrong way. Following your examples, you can either do:
def format_msg(m):
count = len(m) + 4
msg = bytearray()
msg += bytearray(stx)
msg += bytearray(adr)
msg += bytearray(m, "ascii")
msg += bytearray(etx)
cs = 0
i = 0
while i < count-1:
cs ^= msg[i]
i += 1
msg += bytearray(cs)
return msg
or
cmd_ba = stx + bytes('A00',"ascii") + etx
cs = cmd_ba[0] ^ cmd_ba[1] ^ cmd_ba[2] ^ cmd_ba[3] ^ cmd_ba[4]
cmd_ba += bytes(cs)
and the output would be
[2, 65, 48, 48, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
in both cases, as you meant to have.
Upvotes: 1