You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java计算Modbus ASCII协议的纵向冗余校验(LRC)

Modbus ASCII协议LRC校验正确实现方案

问题根源

你当前遇到的结果不符问题由两个常见误区导致:

  1. Java中的byte是有符号8位整数,取值范围为-128~127,大于127的无符号8位值会被转为负数,直接输出数值无法得到正确的十六进制结果
  2. Modbus ASCII的LRC校验对象是未转ASCII编码的原始二进制数据(从从站地址到用户数据域的所有二进制字节),你输入的字节数组是二进制数据转ASCII后的字符编码,不属于LRC的计算输入

Modbus ASCII官方LRC计算规则

  • 对所有参与校验的二进制字节做无符号加法,求和后仅保留低8位,丢弃高位进位
  • 对上述8位求和结果取补码,即使用256减去该8位值,或直接对求和结果取负后保留低8位
  • 最终得到的8位无符号值转成2位大写十六进制ASCII字符,即为Modbus ASCII帧中携带的LRC字段

代码修正与实现

原代码结果说明

你给出的输入byte[] bytes = {31, 30, 31, 30, 31, 31},其中31是十六进制0x31对应ASCII字符1、30是0x30对应ASCII字符0,该数组是二进制数据0x10、0x10、0x11转ASCII后的字符编码,对其计算得到72(十六进制0x48)本身计算逻辑没有问题,只是输入对象错误。

正确Java实现代码

/**
 * 计算Modbus ASCII协议的LRC校验值
 * @param rawBytes 原始二进制校验数据(从站地址到数据域的未编码字节)
 * @return 8位无符号LRC校验值
 */
public static int calculateModbusLRC(byte[] rawBytes) {
    int sum = 0;
    for (byte b : rawBytes) {
        // 转为无符号整数相加,避免有符号数计算偏差
        sum += (b & 0xFF);
    }
    // 取低8位后取补码,再保留低8位得到无符号结果
    return (-(sum & 0xFF)) & 0xFF;
}

/**
 * 将LRC校验值转为Modbus ASCII要求的两位大写十六进制字符串
 * @param lrc calculateModbusLRC方法返回的校验值
 * @return 两位十六进制字符串
 */
public static String getLrcHexStr(int lrc) {
    return String.format("%02X", lrc);
}

验证示例

输入原始二进制字节数组new byte[]{0x01, 0x03, 0x00, 0x00, 0x00, 0x01},求和结果为5,256-5=251,对应十六进制结果FB,完全符合Modbus官方示例的校验结果。

内容的提问来源于stack exchange,提问作者Niranjan Adhav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:36:05