• 締切済み

CRCチェック 多項式の選び方

今、CRCチェックの多項式を何にすればよいか悩んでいます。多項式を選ぶ基準はあるのでしょうか?私は、マイコンのソフト設計を業務にしており、EEPROMにマイコン側で書き込んだデータが正しく、EEPROMから読み出しているかを確認する為にCRCチェックで確認をしようとしています。例えば、EEPROMの容量は1024BYTEで、各セクション=16BYTE(1セクション=16BYTE)単位で各セクションには、SHORT型もしくはCHAR型等のサイズは多種のデータが混在します。セクション単位でCRCチェックを実施しようと考えたいますが、CRCの多項式を選ぶ基準について御教示願いたいです。

みんなの回答

  • mark225
  • ベストアンサー率37% (6/16)
回答No.2

#1です。 私はシリアル通信でCRCやBCCを使いますので、その感覚で回答させて頂いたのですが、どうも貴殿の方がレベルが上の様です(^^; 正直、よく分かりません。 ごめんなさい。(__)

  • mark225
  • ベストアンサー率37% (6/16)
回答No.1

先頭から末尾まで(16バイト)を (1)XOR(排他的論理和)する。 (2)和算した下位8ビットを採用する。 (1)又は(2)の演算結果を17バイト目に添付書き込み。 尚、(1)と(2)では特にどちらが優れていると言う訳ではありませんので「趣味」になると思います。 もし、メモリ容量が許されるのであれば両方を使うと信頼性は上がります。 こんな回答で良かったでしょうか?

mihomayumi
質問者

お礼

ご回答ありがとうございます。 (2)はSUMチェックと思います(データを先頭から末尾まで足しこんで下位1BYTEが0x00とか0xFF等の特定の数値に合わるようなデータを、17BYBE目に埋め込むことと思います)。 (1)がCRCチェックに近いと思いますが。 CRCチェックには一般的にCRC-8/CRC-16/CRC-32等があると思いますが、どの種類のCRCチェック(どの多項式)を使うべきか迷っています。 その為、チェックするデータ長などにより、多項式を選ぶ基準があるのでしょうか。なにを元に多項式を選ぶのでしょうか。との事が知りたいです。 たとえば、データ長で多項式を選ぶ基準があるとすれば、下記のような構造体(計4BYTE)のデータをCRCチェックで実施する場合 short/char/char 多項式では何を選ぶべきなのでしょうか。 ご教示願いたいです。

関連するQ&A

  • 水平垂直パリティチェックとCRC方式について

    質問させてください。 基本情報処理試験において、誤り訂正方式の一つとして ・水平垂直パリティチェック ・CRC方式 というものがあります。 水平垂直パリティチェックは、ビット列を縦横に確認してデータに誤りがないか確認する方法、 CRC方式は、生成多項式という特別な式でデータに誤りがないか確認する方法 ということはわかるのですが、 それぞれのメリットデメリットは何でしょうか? 例えば、CRC方式では水平垂直パリティチェックではできない、2ビット以上の誤り訂正ができたりするのでしょうか? どなたか回答をお願いします。

  • CRCの計算方法について

    色々なサイトを参考にして、自分なりにCRC-ITU-TでCRCを計算する関数を作成しました。 いまいち理解が浅く、そのCRCの値が正しいのか判断できずに困っています。 以下にソースを載せます。 アドバイスを、どうかよろしくお願いします。 unsigned short Crc(unsigned char *Data, unsigned long num) {   unsigned short vCrc;    //CRCを計算する変数   unsigned char vData;   unsigned long i;   int j;   vCrc = 0;   vData = 0;   //初期化   for(i = 0; i <= num; i++){     vData = *(Data+i);   //1byte読み込み     for(j = 0; j < 8; j++){       //CRC計算変数がシフトで桁あふれする場合       if((vCrc & 0x8000) != 0){         vCrc = vCrc << 1;   //1bitシフト         vCrc = vCrc ^ 0x1021;  //多項式とXOR       }       else{         vCrc = vCrc << 1;       }       if((vData & 0x80) != 0){         vData = vData << 1;   //データ変数1bitシフト                 vCrc = vCrc ^ 0x0001;  //CRC計算変数に1をXOR       }       else{         vData = vData << 1;       }     }   }   return(vCrc); }

  • CRCについて

    CRCの算出についてなのですが http://www2c.biglobe.ne.jp/~osakana/vc/pc/crc.html こちらのサイトを参考にすると 1. データを一つ(1バイト)とってきます 2. CRC値を左ビットシフトして、桁上がりがあればさらに生成多項式とXORを取ります 3. データを左ビットシフトして、桁上がりがあればCRC値と1のXORを取ります 4. あと7回(1バイト=8ビットなので)2と3を繰り返します 5. 残りのデータがあれば1に戻ります とあります。 例えばアドレス部00000000にデータ01が入っているもの(ファイルサイズ1バイト)を算出しようとした場合 手計算を行うとCRC16は0001、CRC32は00000001になりそうなのですが いくつかのフリーソフトで実際にバイナリエディタを用いて1バイトのファイルを作成し、試して見たところ CRC16が1E0E CRC32がA505DF1B と出ます。 一般的な算出方法では、上記の説明以外に何か別の処理、初期値などがあるのでしょうか? お分かりになる方是非教えてください。 よろしくお願いします。

  • CRCアルゴリズムのZ/2Z上の多項式の係数列とは?

    こんにちはお世話になります。 私はネットワークに興味があるオジサンです。 先日、データリンク層のプロトコル群を勉強していたとき、誤り訂正でCRCが出てきました。 CRC(Cyclic Redundancy Cheak)の解説には、 >ビット列をZ/2Z上の多項式の係数列とみなし, もとのデータにチェックビットを 継ぎ足して必ず特定の生成多項式で割り切れるデータのみを送るようにする. > とありました。 上記の「Z/2Z上」とは何を指しているのでしょうか。 数学が大の苦手ですので優しく解説していただければ幸いです。 何卒よろしくお願い申し上げます。

  • CRC計算方法

    CRCの生成多項式によるmodulo2計算等については一通り調べて理解したつもりですが、実装するとなるとどうしたものかと止まってしまいます。 実装の要求が 「何バイトあるか不明なデータのCRCを計算する」 (CRC-16にて) です。 どなたかお知恵を拝借できないものでしょうか。

  • CRCのアルゴリズムって、どんな計算するんですか?

    こんにちはお世話になります。 私はネットワークに興味があるオジサンです。 先日、データリンク層のプロトコル群を勉強していたとき、誤り訂正でCRCが出てきました。誤り訂正ではパリティーチェックやチェックサム等は聞き覚えがありましたが、CRCは始めて見たので興味を持ち少し調べてみようと思いました。 それが間違いの元でした。 インターネットでCRCの構造を詳しく解説するサイトが少なく、その解説は難しすぎて手におえません。 数学にはめっぽう弱い私には、多項式同士の加減乗除算などは頭痛の肥やしにしかなりません。 今ではCRCが気になって勉強に集中できない状態です。 そこで、表題にもあるCRCのアルゴリズムを、何方か分かり易く教えてくださいませんか。もしくは、CRCのアルゴリズムを簡単に解説している書籍をご存知でしたら教えてください。 カテゴリー(本来は数学系?)が違うかもしれませんが、何卒よろしくお願い申し上げます。

  • Atmel Studioのeepromアドレス

    現在Atmel Studio6.2でATmega88pマイコンのプログラミングを行っています。 https://sourceforge.jp/projects/cc1101driver/scm/svn/blobs/head/branches/test002_AVRS6_20140819/test02/test02/src/main.c AVR studio4.19 + winAVR Cコンパイラで作成していたコードをAtmel Studio6.2に移してコンパイルを行ったところ、EEPROMアドレスへのデータ書き込みが逆になってしまう現象が起きました。 #define EEPROM __attribute__((section(".eeprom"))) ctl_data EEPROM gctl_data; reg_slave EEPROM greg_slave[100]; int EEPROM eprom_level[14]; char EEPROM eprom_fixid[3]; char EEPROM test_mode; char EEPROM monitor_state; int EEPROM wdt_cnt; int EEPROM cnt_loop_break; このようなコードを”AVR studio4.19 + winAVR”の時からしているのですが、このときは ctl_data EEPROM gctl_data; こちらがEEPROMアドレスの0x0000番地から始まっていたのですが、Atmel Studio6.2の場合は、 int EEPROM cnt_loop_break; こちら側が0x0000番地に配置するようになっていて、逆になってしまっています。 この場合、一番最初のアドレスに割り当てするには、コードも逆にして記述する必要がありますでしょうか? どうぞ、ご教示頂きますようお願いいたします。

  • CRC32のデータ送りの方向について

     送信されてくるethernetフレームを受信しながらCRC32を計算し、 FCSチェックを実施するハード(VHDLによる)を作成しようとしています。  ハードの構成は、下記URL(の中程)のような、1bit単位でのxorにより実施しようと考えています。 http://homepage3.nifty.com/izushi/OTN/tn2/index.html  ethernetフレームで計算されるCRC32が、下記パラメータ、 (1)ビットシフト方向:右 (2)生成多項式:0xEDB88320 (3)初期値(0xFFFFFFFF) (4)出力XOR(0xFFFFFFFF) (5)フレームのLSB側(FCSデータが格納されている方)からデータ送り と一致することは判明し、検証も終わったのですが、 フレームはFCS側からではなく、MSB側(MACアドレス側)から転送されてくるため、 (5)と相反し、実装できません。 フレームのLSB側(FCSデータ側)からではなく、MSB側(MACアドレス側)から データを送り、(1)~(5)の条件で求めたCRC32の値を再現することはできるのでしょうか? 「CRC32」、「左送り」などで調べてみたのですが、 下記URLのように、MSB側(格納データのアドレス0側)から計算している例も あったのですが、CRC32の値が(1)~(5)パラメータで求めたものとCRC32の値が異なりました。 http://okwave.jp/qa/q5183760.html  要約すると、同一のデータを使用して、MSB側、LSB側から計算し、 同じCRC32の値となるようなパラメータの組み合わせが有るか無いか、 ということになると思うのですが・・・ よろしくお願いします。

  • バイナリファイルをバイト単位でアクセスするには?

     大サイズのバイナリファイルに対して、perlでチェックサムを調べたりCRCチェックをかけるプログラムを作成したいと考えています。従って、そのバイナリファイルからバイト単位でデータを取り出して、計算するということをしなければならないのですが、いちばん基本的なところの、『バイナリファイルからバイト単位で順番にデータを取り出す方法』がわかりません。  よろしくお願いします。

    • ベストアンサー
    • Perl
  • C言語のキャストについて

    お世話になります。 CRC-16の計算プログラムをC言語でつくりました。 例えば・・・1F 08 00 00 12 34 なら“1F0800001234”と入力すると【EEC2】と表示するプログラムです。 ただ・・・.Net SDKでコンパイルするとできたのですが、Visual C++2008でコンパイルするとエラーが出てしまいます。 (48) : error C2664: 'strlen' : 1 番目の引数を 'unsigned char [256]' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 (52) : error C2664: 'strtol' : 1 番目の引数を 'unsigned char [3]' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 型変換が必要ってことまではわかったのですが・・・必要なのはわかって行き詰まり状態です。。。 どのようしたらよいのでしょうか?ご教授をよろしくお願いします。 ソースは以下の通りです。 #include "stdafx.h" #include <stdio.h> #include <string.h> #include <stdlib.h> unsigned short crc_cal(unsigned short lng, unsigned char *str) { unsigned short crc, i, j, t; t= 0x0000; crc = 0xffff; for (i = 0; i < lng ; i++) { crc ^= (unsigned short) str[i]; t = (unsigned short) str[i]; for (j = 1; j <= 8; j++) { if (crc & 1) { // carry bit on crc = crc >> 1; crc ^= 0xa001; } else { // carry bit off crc = crc >> 1; } } } return crc; } int main(void) { unsigned char str[256],data[128],hexstr[3]; unsigned short crc,CRC,len; while(1) { printf("Please input key (HEX)\n"); scanf("%255s",str); hexstr[2]='\0'; for(len=0; len<(strlen(str)/2) ;len++) { hexstr[0]=str[len*2]; hexstr[1]=str[len*2+1]; data[len]=(unsigned char)strtol(hexstr, NULL, 16); } crc = crc_cal(len,data); CRC = (crc>>8) | (crc<<8); printf("\nCRC16 = %04X\n\n", CRC); } return 0; }