0

I would like to scan through data files from GPS receiver byte-wise (actually it will be a continuous flow, not want to test the code with offline data). If find a match, then check the next 2 bytes for the 'length' and get the next 2 bytes and shift 2 bits(not byte) to the right, etc. I didn't handle binary before, so stuck in a simple task. I could read the binary file byte-by-byte, but can not find a way to match by desired pattern (i.e. D3).

with open("COM6_200417.ubx", "rb") as f:
byte = f.read(1)  # read 1-byte at a time
while byte != b"":
    # Do stuff with byte.
    byte = f.read(1)
    print(byte) 

The output file is:

b'\x82'
b'\xc2'
b'\xe3'
b'\xb8'
b'\xe0'
b'\x00'
b'@'
b'\x13'
b'\x05'
b'!'
b'\xd3'
b'\x00'
b'\x13'

.... how to check if that byte is == '\xd3'? (D3) also would like to know how to shift bit-wise, as I need to check decimal value consisting of 6 bits (1-byte and next byte's first 2-bits). Considering, taking 2-bytes(8-bits) and then 2-bit right-shift to get 6-bits. Is it possible in python? Any improvement/addition/changes are very much appreciated.

ps. can I get rid of that pesky 'b' from the front? but if ignoring it does not affect then no problem though.

Thanks in advance.

avocadoLambda
  • 1,332
  • 7
  • 16
  • 33
Fakir
  • 139
  • 11

1 Answers1

1

'That byte' is represented with a b'' in front, indicating that it is a byte object. To get rid of it, you can convert it to an int:

thatbyte = b'\xd3'
byteint = thatbyte[0]  # or
int.from_bytes(thatbyte, 'big')  # 'big' or 'little' endian, which results in the same when converting a single byte

To compare, you can do:

thatbyte == b'\xd3'

Thus compare a byte object with another byte object. The shift << operator works on int only

To convert an int back to bytes (assuming it is [0..255]) you can use:

bytes([byteint])   # note the extra brackets!

And as for improvements, I would suggest to read the whole binary file at once:

with open("COM6_200417.ubx", "rb") as f:
    allbytes = f.read() # read all
    for val in allbytes:
        # Do stuff with val, val is int !!!
        print(bytes([val]))
Ronald
  • 2,930
  • 2
  • 7
  • 18
  • Thanks. But why this one is not working? Can not find '\xd3' in the file. check_D3 = b'\xd3' with open("COM6_200417.ubx", "rb") as f: byte = f.read(1) # read 1-byte at a time while byte != b"": # Do stuff with byte. byte = f.read(1) if byte == check_D3: print('Found D3: ') else: exit() – Fakir Jun 17 '20 at 13:14
  • `else: exit()` immediately quits the program. So if the first byte didn't match, the program already quits. – Ronald Jun 17 '20 at 13:24
  • oh, yes. thanks. Its OK now. Regarding your suggestion about reading the entire file, here I am using a fixed size binary file for testing, but for real use, GPS receiver will continuously send data in every second. So I have to continuously scan and if I find a 'D3' then check the next byte for data-length, then another 6-bits if they are either of two particular number or not. If so, then send that data chunk (as found earlier from data-length, and which may vary) for transmission. If no 'D3' or that numbers are not found, discard it and wait for the next feed. It will continue. – Fakir Jun 17 '20 at 13:39
  • Glad that it works. You're right about not reading the whole file at once when it is continuously being updated. – Ronald Jun 17 '20 at 13:44