利用python给文件加CRC校验信息
HELLO,大家好,好久不見,最近太忙了, 幾個月沒有更新文章了。
最近在項目開發過程中,做每個項目的bootloader升級時,就得修訂對應的頭部打包腳本,或者是有界面的打包工具,都需要把對應的廠商、項目相關的信息手動輸入,每打包一次,需要手動輸入一次這些項目相關的數據,太麻煩了!!!
本文,將使用python+配置文件的方式,自動讀取源bin文件并自動生成可定制化的帶頭部的目的文件。
廢話不多說,見我72變。
- 首先, 需要編寫配置文件,我提供一個配置文件案例: 將其保存為xxxx.headconfig
注意文件名字不重要,后綴名一定需要是.headconfig
具體怎么增加填充修訂xxxx.headconfig,如下文件,請自行填充。
hello, 這是自動打包頭部的工具,請按照項目屬性進行配置.
首先,我們需要配置編譯生成的輸出的文件名【可帶編譯路徑】:
======================================================
0、>>testota.bin>>
然后,我們需要設置升級文件頭部信息,請按照項目屬性進行配置.
================升級文件頭部配置起始====================
================請按規定修訂定制值======================
1、廠商ID:8字節
##XXXX1234##
2、產品規格:8字節
##XXXX5678##
3、硬件版本號:3字節
##V001##
4、固件版本號:3字節
##V001##
5、...
================升級文件頭部配置結束====================
最后,我們需要設置輸出文件名信息,請按照項目屬性進行配置.
================輸出文件名配置起始======================
================請按規定修訂定制值======================
1、項目名稱:
@@XXX123@@
2、硬件版本號
@@V100@@
3、固件版本號
@@V100@@
4、...
================輸出文件名配置結束======================
再見
- 其次,編寫python解析該文件,具體代碼我直接給出:
- 測試環境為windows
import crcmod
import re
import os
import sys
# 方法1, 與方法2效果一致
cr16_xmodem = crcmod.predefined.mkCrcFun('modbus')
# 方法2, 與方法1效果一致
# cr16_xmodem = crcmod.mkCrcFun(0x18005, initCrc=0xFFFF, rev=True, xorOut=0x0000)
# print(hex(cr16_xmodem(bytearray(data))))
header_mes = []
out_bin = []
in_bin = []
# 廠商ID:8字節
# 產品規格:8字節
# 硬件版本號:4字節
# 固件版本號:4字節
head_conf_len = [8, 8, 4, 4]
HEADER_LENGTH = 64
TOOLS_VERSION = 'V1.0.0'
print('')
print('**************************科學防疫,健康生活**************************')
print('* *')
print('**************************自動打包頭部工具***************************')
print('* *')
print('**************************工具版本號:%s%s' % (TOOLS_VERSION,'**************************'))
str_update_pat = re.compile(r'\##(.*)\##')
str_outpath_pat = re.compile(r'\@@(.*)\@@')
str_in_bin_path_pat = re.compile(r'\>>(.*)\>>')
# 提取文件夾下的地址+文件名
def file_name(file_dir, file_pat):
L = []
for root, dirs, files in os.walk(file_dir):
for file in files:
if os.path.splitext(file)[1] == file_pat:
L.append(os.path.join(root, file))
return L
# 獲取頭部配置文件
config_path_list = file_name('.', '.headconfig')
config_path = ''
for conf in config_path_list:
config_path += conf.strip();
print('頭部配置文件:%s' % conf)
if (len(config_path_list) != 1):
print('頭部配置文件不存在或者存在多份!')
os.system('cmd')
sys.exit(1)
with open(config_path, 'rt', encoding='utf8') as conf:
configs = conf.readlines()
for line in configs:
header_mes += str_update_pat.findall(line)
out_bin += str_outpath_pat.findall(line)
in_bin += str_in_bin_path_pat.findall(line)
# 拼接頭部填充值
header_mes_str = ''
header_mes_one_len = []
for line in header_mes:
header_mes_one_len.append(len(line.strip()))
header_mes_str += line
# 拼接輸出文件名
out_bin_path = ''
for line in out_bin:
out_bin_path += line.strip() + '-'
# 拼接輸入文件名
in_bin_path = ''
for line in in_bin:
in_bin_path += line.strip()
out_bin_path = out_bin_path.rstrip('-')
out_bin_path += '-UP.bin'
print('頭部數據:%s' % header_mes_str)
print('輸出文件名:%s' % out_bin_path)
print('輸入文件路徑:%s' % (in_bin_path))
if header_mes_one_len != head_conf_len:
print('頭部配置不符合規范,請檢查頭部配置!')
os.system('cmd')
sys.exit(2)
if(os.path.exists(in_bin_path) != True):
print('輸入文件不存在!')
os.system('cmd')
sys.exit(3)
try:
srcbin_len = os.path.getsize(in_bin_path)
with open(in_bin_path, 'rb') as sf:
srcbin = sf.read()
except UnicodeError:
print('文件編碼出錯!')
else:
print('源文件的長度:%d' % srcbin_len)
srcbin_crc = cr16_xmodem(srcbin)
print('源文件CRC值:', hex(srcbin_crc))
header_mes = list(header_mes_str.encode('utf-8'))
srcbin_len_bytes = int(srcbin_len).to_bytes(4, byteorder='big', signed=False)
for i in range(len(srcbin_len_bytes)):
header_mes.append(srcbin_len_bytes[i])
srcbin_crc_bytes = int(srcbin_crc).to_bytes(2, byteorder='big', signed=False)
for i in range(len(srcbin_crc_bytes)):
header_mes.append(srcbin_crc_bytes[i])
header_mes_crc = cr16_xmodem(bytearray(header_mes))
print('頭部CRC【填充0xFF前】:', hex(header_mes_crc))
head_mes_crc_bytes = int(header_mes_crc).to_bytes(2, byteorder='big', signed=False)
for i in range(len(head_mes_crc_bytes)):
header_mes.append(head_mes_crc_bytes[i])
print('填充前頭部的長度:%d' % (len(header_mes)))
for i in range(len(header_mes), HEADER_LENGTH):
header_mes.append(0xFF)
print('填充后頭部的長度:%d' % (len(header_mes)))
with open(out_bin_path, 'wb') as out:
out.write(bytearray(header_mes))
out.write(bytearray(srcbin))
with open(out_bin_path, 'rb') as rout:
outbin_file = rout.read()
outbin_len = os.path.getsize(out_bin_path)
print('填充頭部后的輸出文件長度:%d' % outbin_len)
print('填充頭部后的輸出文件CRC:', hex(cr16_xmodem(outbin_file)))
if ((srcbin_len + HEADER_LENGTH) != outbin_len):
print('**************************頭部填充失敗了**************************')
else:
print('**************************頭部填充成功了**************************')
print('')
os.system('cmd')
- 為了能在沒有安裝python環境的電腦上運行,此處將python腳本進行打包成exe文件:
//將保留打印輸出調試信息
pyinstaller -F --clean auto_add_header.py
//如果不保留打印調試信息
pyinstaller -F -w --clean auto_add_header.py
//可以修改exe文件圖標,一定需要是.ico文件
pyinstaller -F -i test.ico auto_add_header.py
- 可以在dist文件夾下生成auto_add_header.exe文件
- 準備好test.bin, head_mes.headconfig, auto_add_header.exe,雙擊auto_add_header.exe文件, 會有如下輸出:
如果頭部配置文件輸入不符合規范,如:
執行窗口會有如下輸出:
好了,差不多了,工具拿走不謝!
最后,希望大家科學防疫,健康生活!!!
總結
以上是生活随笔為你收集整理的利用python给文件加CRC校验信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mfc 找到字符串中字符_[LeetCo
- 下一篇: python核心数据类型_Python核