5

我试过维基百科的例子: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”,我做错了什么?

谢谢。

4

6 回答 6

14

这是一个清理后的版本,它不会执行所有那些无用的操作(而不是每次都丢弃高位,它们最终会被一次性丢弃),它给出了您观察到的结果。这是使用加法的版本,但最后有一个否定 - 还不如减去并跳过否定。即使在溢出的情况下,这也是一个有效的转换。

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

这是替代 LRC(一个简单的字节异或)

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

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

于 2012-10-09T11:46:02.037 回答
5

猜猜这个看起来更酷;)

public static byte calculateLRC(byte[] bytes)
{
    return bytes.Aggregate<byte, byte>(0, (x, y) => (byte) (x^ y));
}
于 2013-09-10T22:15:09.630 回答
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);
    }
于 2013-10-09T11:24:11.427 回答
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;
    }
于 2013-03-16T15:24:30.417 回答
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;
} 
于 2019-05-07T17:57:49.120 回答
-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;
}
于 2013-08-08T21:46:14.500 回答