質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C

    3711questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

CRC32(反転)の受信時チェックの方法について

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,336

dashi

score 4

[背景]
現在、CRC32(反転)の演算・複合(受信時チェック)の実装に挑戦しています。

以下のgetCrc32()に文字列"123456789"を入力値として演算し、
CRC値を計算すると「0xcbf43926」が取得できます。
この結果は、いくつかのネット上の演算器の結果と一致しており、
正しい値であると認識しております。

CRC演算器(※一例)
http://lazesoftware.com/tool/hash/

次に、受信側でこの「0xcbf43926」を付与したデータを入力として、
再度同じgetCrc32()を使用し、以下添付のソースコードの実装にて、
CRC値を計算した結果が「0」とならず、結果、受信NGと判定してしまいます。
※ただし、CRC32(標準):「0x04C11DB7」でも同じ手順を行い確認しましたが、
結果は「0」となり、正しい値であることは確認できました。

[質問事項]
そこで、以下についてご教授をお願いできませんでしょうか。
1.CRC32(反転)においても、「入力データ+CRC32値(①)」に対して、
①を算出した際の同じ演算を行うと「0」になる認識に誤りはありませんでしょうか。

2.受信時のチェック方法の認識が誤っている場合、正しいチェック方法をご教授いただけませんでしょうか。
参考HP等をご紹介いただけると助かります。

■CRCデータ 受信チェック
    data[0] = 0x31; //ASCII文字 入力データStart
    data[1] = 0x32;
    data[2] = 0x33;
    data[3] = 0x34;
    data[4] = 0x35;
    data[5] = 0x36;
    data[6] = 0x37;
    data[7] = 0x38;
    data[8] = 0x39; //ASCII文字 入力データEnd
    data[9] = 0xcb; //CRC32(反転)値 Start
    data[10] = 0xf4;
    data[11] = 0x39;
    data[12] = 0x26;//CRC32(反転)値 End
    crc=0xFFFFFFFF; //初期値
    for (i = 0; i<13; i++) {
      crc = getCrc32(crc, data[i]);
    }
  ret = ~crc; //入力データを最後まで入れたためbit反転してCRC値を確定

    ★CRC値付きのデータを入力としているため、retが0になることを期待★

■CRCデータ 計算関数
/* 1byte単位のCRC32計算
unsigned long getCrc32(unsigned long regist, unsigned char targetData)
{
    unsigned char i_cnt;
    unsigned char crcProc;                   /* CRC計算実施フラグ */

    for(i_cnt = 0; i_cnt < 8; i_cnt++)
    {
        if((targetData >> i_cnt) & 1)
        {
            regist ^= 1;
        }
        crcProc = (regist & 1);
        regist >>= 1;
        /* registから溢れが発生したら生成多項式とのXORを実施 */
        if(1 == crcProc)
        {
            regist ^= 0xEDB88320U;
        }
    }
    return regist;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

// crcを熟知しているわけではないので、こういうことではないかという推測なのですが...

crcが0になるというのは、
「カウンタ(regist)にカウンタと同じビット列を入力すれば、xorしているところ(regist ^= 1;)が必ず0になるから、カウンタサイズ分回せば、カウンタが0になる」
ということだと思います。
なので、ご提示のコードの場合最後に反転しているので0にすることは出来ませんがffffffffには出来ると思います。
また、カウンタを右へシフトし、入力バイトを下位ビットから読み取っているので、crcのバイトオーダーを逆順にする必要があります。

    data[9] = 0xcb; //CRC32(反転)値 Start
    data[10] = 0xf4;
    data[11] = 0x39;
    data[12] = 0x26;//CRC32(反転)値 End


の部分を

    data[12] = 0xcb ^ 0xff; //CRC32(反転)値 Start
    data[11] = 0xf4 ^ 0xff;
    data[10] = 0x39 ^ 0xff;
    data[9]  = 0x26 ^ 0xff; //CRC32(反転)値 End

にして実行すれば、retはffffffffになるはずです。


といいますか、

ret = ~crc; //入力データを最後まで入れたためbit反転してCRC値を確定


をコメントアウトして、crcのバイトオーダーを逆順にすれば、
期待通りcrc=0になるのではないでしょうか。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/24 13:02

    Ichigo Tarutoさん

    回答ありがとうございました。
    また、詳細に説明いただきありがとうございました。
    お陰様で原理が理解できました。

    ご教授いただいた内容で動作確認を行った結果「0」になることが確認できました。
    取り急ぎご報告いたします。
    以上です。

    キャンセル

0

①がそもそも誤っているかと思います。
②は、普通に長さから4を引いたもののcrcを計算して、最後の4byteと比較すればいいだけかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/24 12:19

    takeshiさん

    回答ありがとうございます。

    >普通に長さから4を引いたもののcrcを計算して、最後の4byteと比較
    こちらはその通りなのですが、CRC値算出時と受信チェック時のアルゴリズムを分けることで精度を上げたいと考えております。
    ※たとえば、CRC値算出時のアルゴリズムが誤っていて不正なCRC値が取得された場合でも、受信側でも同じアルゴリズムを使用して算出すればOKとなってしまうため

    >①がそもそも誤っているかと思います
    反転の方式を使用すると標準の方法では使えた余り「0」のチェック方法は使えないということなんですね。

    ネット上にはCRC値の算出のアルゴリズムはいくつか掲載されているので、(テーブルを使う方法とか)
    送信側、受信側でCRC計算のアルゴリズムを分けてチェックするしかないでしょうか。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3711questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。