2017-07-19 40 views
0

我正在嘗試使用C#生成一個有效的PPP幀檢查序列(FCS)。我已經實施的代碼基於this answer計算PPP幀檢查序列

public static class Crc16 
{ 
    const ushort polynomial = 0x8408; 
    static readonly ushort[] fcstab = new ushort[256]; 

    // This is the fcstab from RFC1662 
    // https://tools.ietf.org/html/rfc1662#ref-7 
    //static readonly ushort[] fcstab = new ushort[] { 
    //  0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 
    //  0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 
    //  0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 
    //  0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 
    //  0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 
    //  0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 
    //  0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 
    //  0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 
    //  0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 
    //  0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 
    //  0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 
    //  0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 
    //  0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 
    //  0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 
    //  0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 
    //  0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 
    //  0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 
    //  0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 
    //  0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 
    //  0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 
    //  0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 
    //  0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 
    //  0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 
    //  0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 
    //  0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 
    //  0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 
    //  0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 
    //  0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 
    //  0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 
    //  0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 
    //  0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 
    //  0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 
    // }; 

    static Crc16() 
    { 
     ushort value; 
     ushort temp; 
     for (ushort i = 0; i < fcstab.Length; ++i) 
     { 
      value = 0; 
      temp = i; 
      for (byte j = 0; j < 8; ++j) 
      { 
       if (((value^temp) & 0x0001) != 0) 
       { 
        value = (ushort)((value >> 1)^polynomial); 
       } 
       else 
       { 
        value >>= 1; 
       } 
       temp >>= 1; 
      } 
      fcstab[i] = value; 
     } 
    } 

    /// <summary>Method that computes the checksum.</summary> 
    /// <param name="buff">The input <see cref="byte[]"/> to calculate the checksum off of.</param> 
    /// <example> 
    /// byte[] fcs = Crc16.ComputeChecksumBytes(buff) 
    /// </example> 
    /// <returns></returns> 
    public static byte[] ComputeChecksumBytes(byte[] buff) 
    { 
     ushort fcs = 0xFFFF; 
     for (int i = 0; i < buff.Length; i++) 
     { 
      byte index = (byte)((fcs^buff[i]) & 0xff); 
      fcs = (ushort)((fcs >> 8)^fcstab[index]); 
     } 
     fcs ^= 0xFFFF; 
     var lsb = (fcs >> 8) & 0xff; 
     var msb = fcs & 0xff; 
     return new byte[] { (byte)msb, (byte)lsb }; 
    } 
} 

良好的部分是,獲取生成的FCS表(fcstab[])是RFC 1662看出因此證實在構造編碼是正確的相同的表。

該問題似乎與ComputeChecksumBytes()方法。

我有一個輸入PPP數據包7E FF 03 C0 21 01 00 00 0E 02 06 00 00 00 00 07 02 08 02 DD 31 7E

我從this link知道,「FCS計算在整個 PPP數據包,不包括啓動和停止標誌(7E)。」這給我留下了FF 03 C0 21 01 00 00 0E 02 06 00 00 00 00 07 02 08 02 DD 31

我也從that link知道FCS八比特組(DD 31)要「等於零」。這使我與FF 03 C0 21 01 00 00 0E 02 06 00 00 00 00 07 02 08 02 00 00

當我用該輸入字節數組調用Crc16.ComputeChecksumBytes時,我的實際計算FCS結果爲C0 0E

我所做的一切似乎都是正確的,但我仍然不知道爲什麼我沒有得到在原始數據包中計算的DD 31

任何幫助將不勝感激!

+1

零應該是'c00e',而不是'2d24'。一定還有其他的錯誤。 –

回答

1

只要做到沒有兩個0的結尾。

+2

一些額外的解釋對未來的讀者會有好處。你是一個非常高的代表用戶,你知道好的答案通常有更多的解釋,否則他們會被標記(就像這樣做!)。我相信它可能會回答這個問題,但你需要解釋它爲什麼會這樣做。 - 來自評論。 –

+1

OP將需要解釋爲什麼他們把兩個0放在第一位!我不知道他們爲什麼這樣做。 –

+0

是的,我承認我很困惑,但我覺得我至少應該留下評論,這樣我可以在評論隊列中點擊'看起來好'按鈕! –