使用python对通讯报文校验,RC&CRC校验,解析CAN报文

from PySide2.QtWidgets import QApplication, QTextBrowser, QFileDialog, QDialog
from threading import Thread
from PySide2.QtCore import Signal, QObject
from datetime import datetime
from ui_e2ewindow import Ui_MainWindow
import os


def ValidDataCheck(line_data, Frame_DLC, data_Length, message_start, log):
    data = line_data.split()  # 将字符串按空格拆分成字符串列表

    data_state = False  # 默认该行字符串不是有效的检查数据
    date_error = False  # 默认该行字符串可能是有效的检查数据
    global message_start_auto, line_label

    # 通过字符串长度来否决数据有效性
    if len(data) <= data_Length or len(data) < message_start + Frame_DLC:
        # 如果报文长度小于设置最小长度 或 报文长度小于起始字节+DLC长度
        date_error = True

    if date_error:
        valid_check_str = 'line ' + str(line_label) + \
                          ' ' + line_data.replace("\n", "") + ' 无效报文,长度不满足条件'
        log.write(valid_check_str + '\n' + '\n')
        pass
    else:
        # 通过检查字符串中是否存在报文来判断是否是有效数据
        sum_cal = 0
        if message_start == -1:
            for i in range(0, len(data)):
                # 自动匹配寻找报文起始位置,从头依次寻找连续DLC长度的两字节报文
                if len(data[i]) == 2:
                    sum_cal = sum_cal + 1
                else:
                    sum_cal = 0

                if sum_cal >= Frame_DLC:
                    data_state = True
                    message_start_auto = i - Frame_DLC + 1
                    break   # 一旦寻找到DLC长度的报文,退出继续寻找
        else:
            for j in range(message_start, message_start + Frame_DLC):
                # 指定报文起始位,则直接验证是否连续DLC长度均为2字节报文
                if len(data[j]) == 2:
                    sum_cal = sum_cal + 1
                else:
                    sum_cal = 0

                if sum_cal >= Frame_DLC:
                    data_state = True
                    message_start_auto = message_start
                    break   # 一旦寻找到DLC长度的报文,退出继续寻找

        if data_state:
            message_start_auto_str = 'line ' + str(
                line_label) + ' 有效报文,报文起始于第' + str(message_start_auto + 1) + ' 个字符段'
        else:
            message_start_auto_str = 'line ' + str(
                line_label) + ' ' + line_data.replace("\n", "") + ' 无效报文,未能成功自动匹配报文起始字符段' + '\n'
        log.write(message_start_auto_str + '\n')
    return data_state


# 匹配检查的CAN ID
def FrameMatch(line_data, frame_lst, id_seq, log):
    data = line_data.split()  # 将字符串按空格拆分成字符串列表
    match_id = ''
    global id_sequence_auto, line_label, dlc_length, message_start_auto
    id_sequence_auto = -1

    if id_seq == -1:
        match_str = 'line ' + str(line_label) + ' 自动匹配报文ID'
        log.write(match_str + '\n')
    for i in range(0, len(frame_lst)):
        if id_seq == -1:
            for j in range(0, len(data)):
                if j in range(message_start_auto, message_start_auto + dlc_length):
                    pass  # 数据区不检查ID
                else:
                    try:
                        compare = int(data[j], 16) == int(frame_lst[i], 16)
                    except ValueError:
                        pass
                    else:
                        if compare:
                            match_id = frame_lst[i]
                            id_sequence_auto = j
                            break  # 寻找到ID,不再继续在本行匹配
        else:
            try:
                compare = int(data[id_seq], 16) == int(frame_lst[i], 16)
            except ValueError:
                pass
            else:
                if compare:
                    match_id = frame_lst[i]
                    id_sequence_auto = id_seq
        if match_id != '':
            break  # 寻找到某ID,不再继续寻找其他ID

    if (id_sequence_auto != -1) and (
            id_sequence_auto not in range(message_start_auto, message_start_auto + dlc_length)):
        id_sequence_auto_str = 'line ' + str(
            line_label) + ' 成功匹配到指定报文ID,位于第' + str(id_sequence_auto + 1) + '个字符段,报文ID为 ' + match_id
    else:
        match_id = ''
        id_sequence_auto_str = 'line ' + str(
            line_label) + ' ' + line_data.replace("\n", "") + ' 未成功匹配到指定报文ID' + '\n'
    log.write(id_sequence_auto_str + '\n')
    return match_id


def rcCheck(message, match_id):
    global rc_old, rc_ini, frame_list, rc_sequence, rc_mask, rc_max, line_label
    for i in range(0, len(frame_list)):
        if int(match_id, 16) == int(frame_list[i], 16):
            if rc_ini[i] == 1 and (message[rc_sequence] & rc_mask) != (rc_old[i] + 1) % (rc_max + 1):
                rc_old[i] = message[rc_sequence] & rc_mask
                return False
            else:
                rc_old[i] = message[rc_sequence] & rc_mask
                rc_ini[i] = 1
                return True
            break


def crcCheck(message):
    global algorithm_type, message_start_auto, dlc_length, crc_sequence, ini_xor, poly, result_xor
    crcCheck_st = False
    if algorithm_type == 'XOR':
        CRC_result = 0
        for i in range(0, dlc_length - 1):
            if i == crc_sequence:
                i = i + 1
            else:
                CRC_result = CRC_result ^ message[i]
    else:
        CRC_result = ini_xor
        for i in range(0, dlc_length - 1):
            if i == crc_sequence:
                i = i + 1
            else:
                CRC_result = CRC_result ^ message[i]
            for j in range(
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值