You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							92 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							92 lines
						
					
					
						
							2.5 KiB
						
					
					
				| import sys
 | |
| import json
 | |
| # pip2 install msgpack-python
 | |
| import msgpack
 | |
| import zlib
 | |
| import os
 | |
| import logging
 | |
| 
 | |
| from Crypto.Cipher import AES
 | |
| 
 | |
| ext = ".gz"
 | |
| SWAG = '\xde\xe2\x11\x15VVC\xf2\x8ep\xd7\xe4\x87\x8d,9'
 | |
| 
 | |
| def compress_json(in_file, out_file):
 | |
|   logging.debug("compressing %s -> %s", in_file, out_file)
 | |
| 
 | |
|   errors = 0
 | |
| 
 | |
|   good = []
 | |
|   last_can_time = 0
 | |
|   with open(in_file, 'r') as inf:
 | |
|     for ln in inf:
 | |
|       ln = ln.rstrip()
 | |
|       if not ln: continue
 | |
|       try:
 | |
|         ll = json.loads(ln)
 | |
|       except ValueError:
 | |
|         errors += 1
 | |
|         continue
 | |
|       if ll is None or ll[0] is None:
 | |
|         continue
 | |
|       if ll[0][1] == 1:
 | |
|         # no CAN in hex
 | |
|         ll[1][2] = ll[1][2].decode("hex")
 | |
|         # relativize the CAN timestamps
 | |
|         this_can_time = ll[1][1]
 | |
|         ll[1] = [ll[1][0], this_can_time - last_can_time, ll[1][2]]
 | |
|         last_can_time = this_can_time
 | |
|       good.append(ll)
 | |
| 
 | |
|   logging.debug("compressing %s -> %s, read done", in_file, out_file)
 | |
|   data = msgpack.packb(good)
 | |
|   data_compressed = zlib.compress(data)
 | |
|   # zlib doesn't care about this
 | |
|   data_compressed += "\x00" * (16 - len(data_compressed)%16)
 | |
|   aes = AES.new(SWAG, AES.MODE_CBC, "\x00"*16)
 | |
|   data_encrypted = aes.encrypt(data_compressed)
 | |
|   with open(out_file, "wb") as outf:
 | |
|     outf.write(data_encrypted)
 | |
| 
 | |
|   logging.debug("compressing %s -> %s, write done", in_file, out_file)
 | |
| 
 | |
|   return errors
 | |
| 
 | |
| def decompress_json_internal(data_encrypted):
 | |
|   aes = AES.new(SWAG, AES.MODE_CBC, "\x00"*16)
 | |
|   data_compressed = aes.decrypt(data_encrypted)
 | |
|   data = zlib.decompress(data_compressed)
 | |
|   msgs = msgpack.unpackb(data)
 | |
|   good = []
 | |
|   last_can_time = 0
 | |
|   for ll in msgs:
 | |
|     if ll[0][1] == 1:
 | |
|       # back into hex
 | |
|       ll[1][2] = ll[1][2].encode("hex")
 | |
|       # derelativize CAN timestamps
 | |
|       last_can_time += ll[1][1]
 | |
|       ll[1] = [ll[1][0], last_can_time, ll[1][2]]
 | |
|     good.append(ll)
 | |
|   return good
 | |
| 
 | |
| def decompress_json(in_file, out_file):
 | |
|   logging.debug("decompressing %s -> %s", in_file, out_file)
 | |
|   f = open(in_file)
 | |
|   data_encrypted = f.read()
 | |
|   f.close()
 | |
| 
 | |
|   good = decompress_json_internal(data_encrypted)
 | |
|   out = '\n'.join(map(lambda x: json.dumps(x), good)) + "\n"
 | |
|   logging.debug("decompressing %s -> %s, writing", in_file, out_file)
 | |
|   f = open(out_file, 'w')
 | |
|   f.write(out)
 | |
|   f.close()
 | |
|   logging.debug("decompressing %s -> %s, write finished", in_file, out_file)
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|   for dat in sys.argv[1:]:
 | |
|     print(dat)
 | |
|     compress_json(dat, "/tmp/out"+ext)
 | |
|     decompress_json("/tmp/out"+ext, "/tmp/test")
 | |
|     os.system("diff "+dat+" /tmp/test")
 | |
| 
 | |
| 
 |