如何计算纵向冗余校验(LRC)?

c# checksum parity

28319 观看

6回复

我试过维基百科的例子:http//en.wikipedia.org/wiki/Longitudinal_redundancy_check

这是lrc(C#)的代码:

/// <summary>
/// Longitudinal Redundancy Check (LRC) calculator for a byte array. 
/// ex) DATA (hex 6 bytes): 02 30 30 31 23 03
///     LRC  (hex 1 byte ): EC    
/// </summary> 
public static byte calculateLRC(byte[] bytes)
{
    byte LRC = 0x00;
    for (int i = 0; i < bytes.Length; i++)
    {
        LRC = (LRC + bytes[i]) & 0xFF; 
    }
    return ((LRC ^ 0xFF) + 1) & 0xFF;
}   

它说结果是“EC”,但我得到“71”,我做错了什么?

谢谢。

作者: Alexx Perez 的来源 发布者: 2019 年 7 月 15 日

回应 (6)


9

决定

这是一个清理版本,它没有完成所有那些无用的操作(不是每次丢弃高位,而是最后一次丢弃它们),它给出了你观察到的结果。这是使用加法的版本,但最后有一个否定 - 也可以减去并跳过否定。即使在溢出的情况下,这也是有效的转换。

public static byte calculateLRC(byte[] bytes)
{
    int LRC = 0;
    for (int i = 0; i < bytes.Length; i++)
    {
        LRC -= bytes[i];
    }
    return (byte)LRC;
}

这是备用LRC(简单的xor字节)

public static byte calculateLRC(byte[] bytes)
{
    byte LRC = 0;
    for (int i = 0; i < bytes.Length; i++)
    {
        LRC ^= bytes[i];
    }
    return LRC;
}

在这种情况下,维基百科在代码(不编译)和预期结果中都是错误的。

作者: harold 发布者: 09.10.2012 11:46

4

猜猜这个看起来更酷;)

public static byte calculateLRC(byte[] bytes)
{
    return bytes.Aggregate<byte, byte>(0, (x, y) => (byte) (x^ y));
}
作者: Omidoo 发布者: 10.09.2013 10:15

3

如果有人想从字符串中获取LRC字符:

    public static char CalculateLRC(string toEncode)
    {
        byte[] bytes = Encoding.ASCII.GetBytes(toEncode);
        byte LRC = 0;
        for (int i = 0; i < bytes.Length; i++)
        {
            LRC ^= bytes[i];
        }
        return Convert.ToChar(LRC);
    }
作者: amp 发布者: 09.10.2013 11:24

0

更正的维基百科版本如下:

private byte calculateLRC(byte[] b)
    {
        byte lrc = 0x00;
        for (int i = 0; i < b.Length; i++)
        {
            lrc = (byte)((lrc + b[i]) & 0xFF);
        }
        lrc = (byte)(((lrc ^ 0xff) + 2) & 0xFF);
        return lrc;
    }
作者: BarToK 发布者: 16.03.2013 03:24

0

我为Arduino创建了这个以理解算法(当然它不是以最有效的方式编写的)

String calculateModbusAsciiLRC(String input)
{
  //Refer this document http://www.simplymodbus.ca/ASCII.htm

  if((input.length()%2)!=0) { return "ERROR COMMAND SHOULD HAVE EVEN NUMBER OF CHARACTERS"; } 
 // Make sure to omit the semicolon in input string and input String has even number of characters

   byte byteArray[input.length()+1];
   input.getBytes(byteArray, sizeof(byteArray));
    byte LRC = 0;
    for (int i = 0; i <sizeof(byteArray)/2; i++)
    {
      // Gettting the sum of all registers
     uint x=0;
     if(47<byteArray[i*2] && byteArray[i*2] <58) {x=byteArray[i*2] -48;}
     else { x=byteArray[i*2] -55;     }
       uint y=0;
     if(47<byteArray[i*2+1] && byteArray[i*2+1] <58) {y=byteArray[i*2+1] -48;}
     else { y=byteArray[i*2+1] -55;     }
     LRC  += x*16 + y;
    }   
    LRC = ~LRC + 1;   // Getting twos Complement
    String checkSum = String(LRC, HEX);
    checkSum.toUpperCase(); // Converting to upper case eg: bc to BC - Optional somedevices are case insensitve 
    return checkSum;
} 
作者: Hasala Senevirathne 发布者: 07.05.2019 05:57

-1

我意识到这个问题很老了,但我很难搞清楚如何做到这一点。它现在正在工作,所以我想我应该粘贴代码。在我的例子中,校验和需要作为ASCII字符串返回。

public function getLrc($string)
{
    $LRC = 0;
    // Get hex checksum.
    foreach (str_split($string, 1) as $char) {
        $LRC ^= ord($char);
    }
    $hex = dechex($LRC);
    // convert hex to string
    $str = '';
    for($i=0;$i<strlen($hex);$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
    return $str;
}
作者: Charlie 发布者: 08.08.2013 09:46
32x32