1

CRC-16 の値を検証しようとして助けが必要です (CRC-32 の値についても助けが必要です)。私は座ってCRCがどのように機能するかを理解しようとしましたが、空白を描いています.

BD001325E032091B94C412AC私の最初の問題は、メッセージ " " をCRC16 = 12ACに計算するためにオンライン計算機を使用しようとしたときです。ドキュメントには、最後の 2 オクテットが 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

- 編集 -

私はより多くの情報を含めました。私が参照していたドキュメントは、TIA-102.BAAA-A (TIA 標準から) です。ドキュメントには次のように記載されています (可能な限り著作権侵害を回避しようとしています)。

パケット内の最後のブロックは、ユーザー情報の数オクテットおよび/またはパッド オクテットで構成され、その後に 4 オクテットの CRC パリティ チェックが続きます。これは、パケット CRC と呼ばれます。

パケット CRC は、中間ブロックに含まれるすべてのデータ オクテットと最終ブロックのユーザー情報のオクテットにわたってコード化された 4 オクテットの巡回冗長検査です。具体的な計算は以下の通りです。

k を、パケットの CRC を計算するユーザー情報とパッド ビットの総数とします。k メッセージ ビットを次数 k–1 の多項式 M(x) の係数と見なし、0 番目のメッセージ オクテットの MSB を x^k–1 に関連付け、最後のメッセージ オクテットの LSB を 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 + x^30 + x^29 + ... + x^2 + x +1

パケットの CRC 多項式 FM(x) は、次の式から計算されます。

FM(x) = ( x^32 M(x) mod GM(x) ) + IM(x) modulo 2、つまり GF(2)

FM(x) の係数は、x^31 に対応する CRC の 0 番目のオクテットの MSB と x^0 に対応する CRC の 3 番目のオクテットの LSB と共に CRC フィールドに配置されます。

上記の引用では、^引用されたときにフォーマットが同じままではなかったため、力を示しました。何がどうなるかわかりませんが、これは役に立ちますか?

4

3 に答える 3

5

インターネットで見つけた 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;
       }
 }
于 2013-04-25T11:18:03.603 に答える
4
  1. CRC に関する Ross Williams のチュートリアルを読んで、CRC、特定の CRC の定義、およびその実装について理解を深めてください。

  2. revengのWeb サイトには、既知の CRC の優れたカタログと、それぞれの CRC のテスト文字列 (9 バイト: ASCII/UTF-8 の「123456789」) があります。そこには22 の異なる 16 ビット CRCが定義されていることに注意してください。

その同じサイトの reveng ソフトウェアを使用して、16 ビット CRC の場合と同様に、いくつかの例を挙げて、多項式、初期化、後処理、およびビット反転をリバース エンジニアリングできます。(したがって、「reveng」という名前です。)データを調べたところ、次のようになりました。

./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 のいずれにも当てはまりませんが、初期化のみが異なり、それらのいくつかと似ています。

あなたが提供した追加情報は、ビットが逆になっているかどうかに応じて、reven カタログの CRC-32 または CRC-32/BZIP の 32 ビット CRC に関するものです。

于 2013-04-22T20:48:53.270 に答える