2013-04-22 2 views
0

CRC-16 값을 확인하는 데 도움이 필요합니다 (CRC-32 값과 관련하여 도움이 필요함). 나는 앉아서 CRC가 어떻게 작동하는지 이해하려고 노력했지만 빈 그림을 그렸습니다.CRC-16 및 CRC-32 검사

첫 번째 문제는 온라인 계산기를 사용하여 CRC16 = 12AC에 "BD001325E032091B94C412AC"메시지를 계산할 때 발생합니다. 설명서에 마지막 두 옥텟은 CRC16 값이므로 "BD001325E032091B94C4"을 http://www.lammertbies.nl/comm/info/crc-calculation.html 사이트에 입력하고 12AC 대신 5A90을받습니다.

아무도 왜이 값이 다른지, 그리고 CRC16 및 CRC32 값을 계산하는 방법에 대한 코드를 찾을 수 있습니까 (나중에 어떻게 할 것인지 배우려하지만 시간은 지금 허용되지 않습니다)?

좀 더 메시지는 다음과 같습니다 : 좀 더 정보를 포함했다

16000040FFFFFFFF00015FCB 
3C00003144010405E57022C7 
BA00001144010101B970F0ED 
3900010101390401B3049FF1 
09900C800000000000008CF3 
8590000000000000000035F7 
00900259025902590259EBC9 
0200002B00080191014BF5A2 
BB0000BEE0014401B970E51E 
3D000322D0320A2510A263A0 
2C0001440000D60000D65E54 

--Edit--

. 내가 참조했던 문서는 TIA-102.BAAA-A (TIA 표준)입니다. 사용자 정보 및/또는 패드 옥텟의

패킷의 마지막 블록 단계는 여러 옥텟, 4 옥텟 다음 : 다음은 문서 상태는 (가능한 한 많은 저작권 침해를 피하기 위해 노력하고) 무엇인가 CRC 패리티 검사. 이를 패킷 CRC라고합니다.

패킷 CRC가 옥텟 상기 중간 블록에 포함되는 데이터와 마지막 블록의 사용자 정보의 옥텟 온통 부호화 4 옥텟 순환 중복 검사이다. 구체적인 계산 방법은 다음과 같습니다.

k를 패킷 CRC가 계산되는 사용자 정보 및 패드 비트의 총 수라고 가정합니다. 0 번째 메시지의 MSB를 x^k-1로, 마지막 메시지 옥텟의 LSB를 x^k-1로 결합하여 k 번째 메시지 비트를 다항식 M (x) 0. 생성 다항식 GM (x) 및 반전 다항식 IM (x)을 정의하십시오.

GM (x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + X^ 4 + X^2 + X + 1

IM (X) = X^31 + 30 + X^X^29 + ... + X^2 + X +1

패킷 CRC 다항식 FM (x)는 다음 공식을 사용하여 계산됩니다.

FM (X) = (X^32 M (x)를 개조 GM (X)) + IM (X)                         모듈로 2, 즉 GF (2)

FM 계수

가 (x)는 X^(31)에 대응하는 CRC의 제 0 옥텟의 MSB와 함께 CRC 필드 배치에 대응하는 CRC 세 번째 옥텟의 LSB X^0.

위의 인용문에서 인용 할 때 서식이 동일하게 유지되지 않으므로 ^에 권력을 표시했습니다. 나는 무엇이 어떻게 될지는 모르지만 이것이 도움이됩니까?

+0

여기서 12AC 값을 얻었습니까? –

+0

BD001325E032091B94C412AC의 마지막 2 바이트. 예제 블록을 보면 마지막 두 바이트가 항상 체크섬 인 것처럼 보입니다. – egrunin

+0

다른 CRC-16 값이있을 수 있으며, 이는 전적으로 다항식에 따라 다릅니다. – ken2k

답변

4
  1. 읽기 Ross Williams tutorial on CRCs 특정 CRC, 그들의 구현을 정의하는 것을 CRC의 더 나은 이해를 얻을 수 있습니다.

  2. reveng website은 알려진 CRC 카탈로그가 우수하며 테스트 문자열 (9 바이트 : ASCII/UTF-8의 경우 "123456789")의 CRC마다 우수합니다. 다른 22 비트의 16 비트 CRC이 정의되어 있습니다.

같은 사이트의 reveng 소프트웨어

는 16 비트 CRC에 대한이 같은 다항식, 초기화, 후 처리, 비트 반전에게 주어진 몇 가지 예를 리버스 엔지니어링 할 수 있습니다. 하지만,

./reveng -w 16 -s 16000040FFFFFFFF00015FCB 3C00003144010405E57022C7 BA00001144010101B970F0ED 3900010101390401B3049FF1 09900C800000000000008CF3 8590000000000000000035F7 00900259025902590259EBC9 0200002B00080191014BF5A2 BB0000BEE0014401B970E51E 3D000322D0320A2510A263A0 2C0001440000D60000D65E54 

width=16 poly=0x1021 init=0xc921 refin=false refout=false xorout=0x0000 check=0x2fcf name=(none) 

"(없음)"에 의해 표시된 바와 같이, 16 비트 CRC가 아니라고 reveng에 나와있는 (22) 중 하나를 (. 따라서 이름이 "reveng은") 나는 통해 데이터를 달리고있어 그것들은 몇개의 경우와 유사 합니다만, 초기화 만이 다릅니다.

제공되는 추가 정보는 비트가 반전되었는지 여부에 따라 reveng 카탈로그에있는 32 비트 CRC (CRC-32 또는 CRC-32/BZIP)에 대한 것입니다.

+0

CRCs에 대해 배우는 데 많은 시간을 할애 할 필요가 없으므로 이것을 지금 답변으로 표시 할 예정입니다.받는 메시지에 대해 많은 노력을 기울이는 것처럼 들립니다. 링크 및 정보에 감사드립니다. 나는 언젠가 이것들을 재검토하고 그것들을 이해하려고 노력할 것이다. –

2

CRC 계산에 대한 몇 가지 매개 변수가 있습니다. 다항식, 초기 값, 최종 XOR ... 자세한 내용은 Wikipedia을 참조하십시오. CRC는 사용했던 사이트의 CRC와 맞지 않지만 설명서에서 올바른 매개 변수를 찾고 다른 계산기를 사용해보십시오. this one (단, 16 진수 입력을 지원하지 않습니다.)

CRC-16은 보통 checksummed 데이터로 계산됩니다. 와 2 개의 0 바이트를 더한 것. 당신은 아마도 CRC16 함수를 찾고 있는데, 여기서 CRC16(BD001325E032091B94C40000) == 12AC입니다. 이런 식으로 계산 된 체크섬을 사용하면 체크섬이 추가 된 데이터의 CRC가 0으로되어 체크가 더 쉬워집니다. CRC16(BD001325E032091B94C412AC) == 0000

+0

더 많은 정보를 포함하도록 원래 질문을 업데이트했습니다. –

3

저는 인터넷에서 발견 된 C++에서 변환 한 클래스가 있습니다. CRC32를 계산하는 데 long을 사용합니다. 이것은 표준을 따르며 PKZIP, WinZip 및 이더넷에 의해 사용됩니다. 이를 테스트하려면 Winzip을 사용하고 파일을 압축 한 다음이 클래스로 같은 파일을 계산하면 동일한 CRC를 반환해야합니다. 그것은 나를 위해 않습니다.

public class CRC32 
{ 
    private int[] iTable; 

    public CRC32() { 
     this.iTable = new int[256]; 
     Init(); 
    } 

    /** 
    * Initialize the iTable aplying the polynomial used by PKZIP, WINZIP and Ethernet. 
    */ 
    private void Init() 
    { 
     // 0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet. 
     int iPolynomial = 0x04C11DB7; 

     // 256 values representing ASCII character codes. 
     for (int iAscii = 0; iAscii <= 0xFF; iAscii++) 
     { 
      this.iTable[iAscii] = this.Reflect(iAscii, (byte) 8) << 24; 

      for (int i = 0; i <= 7; i++) 
      { 
      if ((this.iTable[iAscii] & 0x80000000L) == 0) this.iTable[iAscii] = (this.iTable[iAscii] << 1)^0; 
      else this.iTable[iAscii] = (this.iTable[iAscii] << 1)^iPolynomial; 
      } 
      this.iTable[iAscii] = this.Reflect(this.iTable[iAscii], (byte) 32); 
     } 
    } 

    /** 
    * Reflection is a requirement for the official CRC-32 standard. Note that you can create CRC without it, 
    * but it won't conform to the standard. 
    * 
    * @param iReflect 
    *   value to apply the reflection 
    * @param iValue 
    * @return the calculated value 
    */ 
    private int Reflect(int iReflect, int iValue) 
    { 
     int iReturned = 0; 
     // Swap bit 0 for bit 7, bit 1 For bit 6, etc.... 
     for (int i = 1; i < (iValue + 1); i++) 
     { 
      if ((iReflect & 1) != 0) 
      { 
      iReturned |= (1 << (iValue - i)); 
      } 
      iReflect >>= 1; 
     } 
     return iReturned; 
    } 

    /** 
    * PartialCRC caculates the CRC32 by looping through each byte in sData 
    * 
    * @param lCRC 
    *   the variable to hold the CRC. It must have been initialize. 
    *   <p> 
    *   See fullCRC for an example 
    *   </p> 
    * @param sData 
    *   array of byte to calculate the CRC 
    * @param iDataLength 
    *   the length of the data 
    * @return the new caculated CRC 
    */ 
    public long CalculateCRC(long lCRC, byte[] sData, int iDataLength) 
    { 
     for (int i = 0; i < iDataLength; i++) 
     { 
      lCRC = (lCRC >> 8)^(long) (this.iTable[(int) (lCRC & 0xFF)^(int) (sData[i] & 0xff)] & 0xffffffffL); 
     } 
     return lCRC; 
    } 

    /** 
    * Caculates the CRC32 for the given Data 
    * 
    * @param sData 
    *   the data to calculate the CRC 
    * @param iDataLength 
    *   then length of the data 
    * @return the calculated CRC32 
    */ 
    public long FullCRC(byte[] sData, int iDataLength) 
    { 
     long lCRC = 0xffffffffL; 
     lCRC = this.CalculateCRC(lCRC, sData, iDataLength); 
     return (lCRC /*& 0xffffffffL)*/^ 0xffffffffL); 
    } 

    /** 
    * Calculates the CRC32 of a file 
    * 
    * @param sFileName 
    *   The complete file path 
    * @param context 
    *   The context to open the files. 
    * @return the calculated CRC32 or -1 if an error occurs (file not found). 
    */ 
    long FileCRC(String sFileName, Context context) 
    { 
      long iOutCRC = 0xffffffffL; // Initilaize the CRC. 

      int iBytesRead = 0; 
      int buffSize = 32 * 1024; 
      FileInputStream isFile = null; 
      try 
      { 
      byte[] data = new byte[buffSize]; // buffer de 32Kb 
      isFile = context.openFileInput(sFileName); 
      try 
      { 
       while ((iBytesRead = isFile.read(data, 0, buffSize)) > 0) 
       { 
        iOutCRC = this.CalculateCRC(iOutCRC, data, iBytesRead); 
       } 
       return (iOutCRC^0xffffffffL); // Finalize the CRC. 
      } 
      catch (Exception e) 
      { 
       // Error reading file 
      } 
      finally 
      { 
       isFile.close(); 
      } 
      } 
      catch (Exception e) 
      { 
      // file not found 
      } 
      return -1l; 
     } 
}