• 締切済み

CRC-CCITT16の算出法

はじめまして。 仕事でconsoleアプリを作ろうとしてるんですがCRC-CCITT(X^16+X^12+X^5+1)の求め方が分かりません。netで色々検索してみたんですが良いsiteがHitしませんでした。 元dataが“0x01”か“0x9201”のどちらかの時に、CRC“A8 FD”になるんですが、どうしても計算結果と違ってしまいます。 どなたか詳しい人がいらっしゃるなら、是非とも教えて下さい。

みんなの回答

  • alicia-y
  • ベストアンサー率40% (85/208)
回答No.1

参考URLに「C言語による最新アルゴリズム事典 」の本の ソースがあるのでそれで試してみてはどうですか?

参考URL:
http://www.vector.co.jp/soft/data/prog/se002453.html
inokun
質問者

お礼

助言ありがとう御座いました。 頑張ってみます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • CRC16計算について

    CRC16のプログラムを作ったのでデバッグしていて気付いた事なのですが (産業装置で使うMODBUS-RTUのソフト) CRC16 x16+x15+x2+1 生成多項式 0xA001 CRC16でCRCを含めたデータを再CRCするとゼロになると言われておりますが そうならないのですが何故でしょう? もちろん、自分の作ったソフトが信用できないので他ソフトで検証 具体例 ベクターにあるCRC16の計算ソフト - CRC16.exe http://blog.goo.ne.jp/masaki_goo_2006/e/50b20edb79f60964faeaefe6fa064469 これに文字列"ABCD" [0x4142,0x4344]を入れて計算実行 出力結果  初期値:0xFFFF、出力XOR:0xFFFF、出力結果、右送り0x0F85 この出力を最初の文字列に追加する 0x4142,0x4344,0x0F85 結果は0xc7e6 となってゼロになりません やりかたが違うのでしょうか? 尚、私の作ったプログラムと上記ソフトの結果が同じです また、ネット上にある同様な他ソフトでも同じ結果でした (もちろんCRC計算条件が同じ物) 尚、上記ソフトで 初期値:0x0000、出力XOR:0x0000、左送り:9AA8 この場合のみCRC追加しての再CRCはゼロになりました ゼロになる場合とならない場合があるのでしょうか?

  • CRC8 ATMの計算方法

    CRC8 ATMの演算を行うツールの検証を行っているのですが、 CRCの机上計算方法を詳しく解説したサイトが無く生成多項式で 割って余りを求めると言う事しかわかりませんでした。 CRCを求める際はCRCの初期値も重要な筈ですが、CRCの初期値は 余りを求める際にどの様に使うのかを開設した物がなく、私に 検証を依頼してきた人に聞いてもまともな回答をもらえません でした(検証を依頼してきた人もちゃんと理解していない?)。 このサイトの別の質問の回答で 1. 与えられたデータの下位 (ビット送りの反対側) に「初期値」   を付加する 2. 生成多項式で割って余りを求める とあったので、その通りに計算しましたが初期値が0x00の時は ツールと机上計算の結果が一致するのですが、初期値0xFFの時は ツールと机上計算の結果が一致しませんでした。 実際の計算過程と結果は下記です。 生成多項式:x8+x2+x1+1(9'b100000111) 入力データ:0x12345678 CRC初期値:0x00 データ左送り、入出力反転なし 机上計算 初期値:0001001000110100010101100111100000000000(0x1234567800) 100000111 ---------------------------------------- 0001001000100010101100111100000000000 100000111 ---------------------------------------- 0001001010010101100111100000000000 100000111 ---------------------------------------- 0001011100101100111100000000000 100000111 ---------------------------------------- 0011101011100111100000000000 100000111 ---------------------------------------- 01101000000111100000000000 100000111 ---------------------------------------- 0101001110111100000000000 100000111 ---------------------------------------- 001001001111100000000000 100000111 ---------------------------------------- 0001000001100000000000 100000111 ---------------------------------------- 0000000010000000000 100000111 ---------------------------------------- 00000011100 なのでCRC(余り)は0x1C(00011100)でツールの結果0x1Cと一致。 CRC初期値:0xFF 机上計算 初期値:0001001000110100010101100111100011111111(0x12345678FF) 100000111 ---------------------------------------- 0001001000100010101100111100011111111 100000111 ---------------------------------------- 0001001010010101100111100011111111 100000111 ---------------------------------------- 0001011100101100111100011111111 100000111 ---------------------------------------- 0011101011100111100011111111 100000111 ---------------------------------------- 01101000000111100011111111 100000111 ---------------------------------------- 0101001110111100011111111 100000111 ---------------------------------------- 001001001111100011111111 100000111 ---------------------------------------- 0001000001100011111111 100000111 ---------------------------------------- 0000000010011111111 100000111 ---------------------------------------- 00011100011 なのでCRC(余り)は0xE3(11100011)でツールの結果0xCDと不一致 となりました。 これは計算の仕方が間違っているのでしょうか? それともツールの結果が間違っているのでしょうか? 何方かCRCの計算に詳しい人、ご回答をお願いします。

  • 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の計算方法について

    色々なサイトを参考にして、自分なりに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); }

  • FDから読み取り出来ません。巡回冗長検索(CRC)エラーというのが出ました。

    FDから読み取り出来ません。巡回冗長検索(CRC)エラーというのが出ました。中身のデータは重要ではありませんので問題ないのですが,これがプレゼン中でたら冷や汗ものでした。家に持って帰って見直しをしていて出ました。 いったい,どういうエラーなのですか? また,こういったエラーのでるFDは破棄?それとも,フォーマットでしょうか?

  • CRC5(X^5+X^3+1)の計算方法

    どなたか、CRC5(X^5+X^3+1)の計算方法を知ってらっしゃる方がおられれば、ご教授下さい。 # サンプルコードつきだと、なお嬉しいのですが CRC5について詳しく解説してくれてるサイトでも結構です。(英文可) どうぞよろしくお願い致します。

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

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

  • CRCの検定コードがどの文字でも同じになった!?

    C言語の初級者が質問します。 講義の課題で、「伝送誤り検出方式として巡回符号方式(CRC:Cyclic Redundancy Check)を使用した場合、送り側でアルファベット6文字の適当な単語を1文字ずつ入力した場合の検定コードを算出しなさい。生成多項式はCRC-16-CCITT(Xの16乗)+(Xの12乗)+(Xの5乗)+1を使用し、検定コードは2byteとする。 この課題に対し、一文字ずつ、検定コードを求めて合計6個の和を出して16進数で表現しようと考え、以下のプログラムを作りました。#include <stdio.h> #include <string.h> #include <stdlib.h> int main () { int t,s,i,m; int l; int flag; int crcReg[10]; // crcRegは一文字ごとのCRCの計算途中過程 res[]は一文字ごとのCRCの最終結果 char inData[6]; //文字列入力 int jyuroku[6]; int crcmax; printf("文字入力(6文字まで):"); gets(inData); // l=strlen(inData); for(i = 0;i < l; i++) { printf("%d番目は16進数で%X\n",i+1,inData[i]); // } printf("各文字の16進asciiは(0x必要か?)"); for(m = 0;m <l;m++) { printf("%d番目のascii:",m+1); scanf("%X", &jyuroku[m]); // } //**********************************(後半)********************************************** for(s=0;s < l; s++) {//文字の数だけ繰り返し crcReg[s]=0xFFFF; //CRCの初期値はどの文字の場合でも同じ printf("%d 番目の16進ascii:%X\n",s+1,jyuroku[s]); // for (t = 0;t < 8; t++) { //入力する16進数は8ビット=1バイト ゆえ8回繰り返し flag = (crcReg[s] ^ jyuroku[s] & 0x01); // 生成多項式をかけるかどうかの判定の前段階 crcReg[s] = crcReg[s] >> 1; //CRCの計算過程を1ビット右にシフト if (flag == 0x01) { //最下位ビットflagが1の時の処理 crcReg[s] = (crcReg[s] ^ 0x8408); //生成多項式は10進数で } else if (flag == 0x00) { } jyuroku[s] = jyuroku[s] >> 1; // asciiコードも1 ビットシフト } printf("CRCの結果は%X\n",crcReg[s]); // } crcmax = crcReg[0]+crcReg[1]+crcReg[2]+crcReg[3]+crcReg[4]+crcReg[5]; printf("\n kekka:%d",crcmax); // return 0; // } しかし、こうするとcrcReg[s](検定コード)がどの文字の場合でも同じ255(16進数ではFF)になって、6文字の単語は常に和が1530になってしまいます。255=16の2乗-1であることが問題解決の鍵だと思うのですが、何か問題点わかりますか?

  • ソフトウェア開発技術者試験(CRCの送信データ)

    何度も、恐縮です。 ソフトウェア開発技術者試験の勉強をしている 普通科、高卒の者です。 CRCの送信データの多項式が理解できません。 110101 を送る時、 A = Xの5乗 + Xの4乗 + Xの2乗 + 1 B = Xの3乗 + Xの2乗 + 1 (疑問1) なぜ、Bがこの式になるのでしょうか? (A)は、解りますが・・・ このAに生成多項式Bの次数(3)を掛け、 結果は、 C = Xの8乗 + Xの7乗 + Xの5乗 + Xの3乗 と、なります。 (疑問2) なぜ、生成多項式Bの次数が(3)なのでしょうか? 一番最初のXの3乗と、考えて良いのでしょうか? 続いて、C/Bの計算をします。                 Xの5乗      + 1               _______________________ _____________ Xの3乗 + Xの2乗 + 1 ) Xの8乗 + Xの7乗 + Xの5乗 + Xの3乗                Xの8乗 + Xの7乗 + Xの5乗                      ___________________________________                      Xの3乗                      Xの3乗 + Xの2乗 + 1                     _________________                      - Xの2乗 - 1 と、答えは、[- Xの2乗 - 1]が余りとなります。 (疑問3) どうすれば、この計算式が成り立つのでしょうか? まず、なぜ、Xの5乗 が上の答えに入るのでしょうか? 以上、3点の質問になります。ご存知の方からすれば 簡単な問題かもしれませんが、宜しくお願い致します。

  • VB.NETの関数プロシージャの書き方を教えてください。

    Public A As String という変数にある文字列データが入っていて、 ボタンを押すとその時に変数X,Y,Zに入っている 文字列を検索してButton1_Clickプロシージャ内に戻って来て KekkaX,KekkaY,KekkaZに数値が入るような関数プロシージャなのですが、 呼び出す部分の書き方と関数のプロシージャ名の書き方を教えて頂きたいです。 検索する部分は自分で出来ると思うので大丈夫です。 Public A As String = "何かの文字列" Button1_Click Dim X,Y,Z As String Dim KekkaX,KekkaY,KekkaZ as Integer '変数Aの中からX,Y,Zを検索したい X="*****" Y="ABCDE" Z="#####" GetKensakuKekka(????????) ←この部分の書き方を教えて下さい。 'KekkaX,KekkaY,KekkaZ 内に検索結果を取得したい Console.WriteLine(KekkaX) Console.WriteLine(KekkaY) Console.WriteLine(KekkaZ) End Sub Function GetKensakuKekka (???????????) ←この部分の書き方を教えて下さい。 ・ ・ ・ End Function よろしくお願い致します。