How can I calculate Longitudinal Redundancy Check (LRC)?

前端 未结 6 871
盖世英雄少女心
盖世英雄少女心 2021-01-19 07:35

I\'ve tried the example from wikipedia: http://en.wikipedia.org/wiki/Longitudinal_redundancy_check

This is the code for lrc (C#):

///          


        
相关标签:
6条回答
  • 2021-01-19 08:05

    The corrected Wikipedia version is as follows:

    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;
        }
    
    0 讨论(0)
  • 2021-01-19 08:15

    If someone wants to get the LRC char from a string:

        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);
        }
    
    0 讨论(0)
  • 2021-01-19 08:19

    Here's a cleaned up version that doesn't do all those useless operations (instead of discarding the high bits every time, they're discarded all at once in the end), and it gives the result you observed. This is the version that uses addition, but that has a negation at the end - might as well subtract and skip the negation. That's a valid transformation even in the case of overflow.

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

    Here's the alternative LRC (a simple xor of bytes)

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

    And Wikipedia is simply wrong in this case, both in the code (doesn't compile) and in the expected result.

    0 讨论(0)
  • 2021-01-19 08:23

    I created this for Arduino to understand the algorithm (of course it's not written in the most efficient way)

    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;
    } 
    
    0 讨论(0)
  • 2021-01-19 08:25

    Guess this one looks cooler ;)

    public static byte calculateLRC(byte[] bytes)
    {
        return bytes.Aggregate<byte, byte>(0, (x, y) => (byte) (x^ y));
    }
    
    0 讨论(0)
  • 2021-01-19 08:30

    I realize that this question pretty old, but I had trouble figuring out how to do this. It's working now, so I figured I should paste the code. In my case, the checksum needs to return as an ASCII string.

    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;
    }
    
    0 讨论(0)
提交回复
热议问题