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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

Q&A

解決済

2回答

8902閲覧

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

dashi

総合スコア14

C

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

0グッド

0クリップ

投稿2017/01/24 01:43

[背景]
現在、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等をご紹介いただけると助かります。

C

1■CRCデータ 受信チェック 2 data[0] = 0x31; //ASCII文字 入力データStart 3 data[1] = 0x32; 4 data[2] = 0x33; 5 data[3] = 0x34; 6 data[4] = 0x35; 7 data[5] = 0x36; 8 data[6] = 0x37; 9 data[7] = 0x38; 10 data[8] = 0x39; //ASCII文字 入力データEnd 11 data[9] = 0xcb; //CRC32(反転)値 Start 12 data[10] = 0xf4; 13 data[11] = 0x39; 14 data[12] = 0x26;//CRC32(反転)値 End 15 crc=0xFFFFFFFF; //初期値 16 for (i = 0; i<13; i++) { 17 crc = getCrc32(crc, data[i]); 18 } 19 ret = ~crc; //入力データを最後まで入れたためbit反転してCRC値を確定 20 21 ★CRC値付きのデータを入力としているため、retが0になることを期待★ 22 23■CRCデータ 計算関数 24/* 1byte単位のCRC32計算 25unsigned long getCrc32(unsigned long regist, unsigned char targetData) 26{ 27 unsigned char i_cnt; 28 unsigned char crcProc; /* CRC計算実施フラグ */ 29 30 for(i_cnt = 0; i_cnt < 8; i_cnt++) 31 { 32 if((targetData >> i_cnt) & 1) 33 { 34 regist ^= 1; 35 } 36 crcProc = (regist & 1); 37 regist >>= 1; 38 /* registから溢れが発生したら生成多項式とのXORを実施 */ 39 if(1 == crcProc) 40 { 41 regist ^= 0xEDB88320U; 42 } 43 } 44 return regist; 45} 46 47

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

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

c

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

の部分を

c

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

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


といいますか、

c

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

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

投稿2017/01/24 03:33

編集2017/01/24 03:47
IchigoTaruto

総合スコア159

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dashi

2017/01/24 04:02

Ichigo Tarutoさん 回答ありがとうございました。 また、詳細に説明いただきありがとうございました。 お陰様で原理が理解できました。 ご教授いただいた内容で動作確認を行った結果「0」になることが確認できました。 取り急ぎご報告いたします。 以上です。
guest

0

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

投稿2017/01/24 02:57

takeshi

総合スコア264

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dashi

2017/01/24 03:19

takeshiさん 回答ありがとうございます。 >普通に長さから4を引いたもののcrcを計算して、最後の4byteと比較 こちらはその通りなのですが、CRC値算出時と受信チェック時のアルゴリズムを分けることで精度を上げたいと考えております。 ※たとえば、CRC値算出時のアルゴリズムが誤っていて不正なCRC値が取得された場合でも、受信側でも同じアルゴリズムを使用して算出すればOKとなってしまうため >①がそもそも誤っているかと思います 反転の方式を使用すると標準の方法では使えた余り「0」のチェック方法は使えないということなんですね。 ネット上にはCRC値の算出のアルゴリズムはいくつか掲載されているので、(テーブルを使う方法とか) 送信側、受信側でCRC計算のアルゴリズムを分けてチェックするしかないでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問