![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
色々なサイトを参考にして、自分なりに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);
}
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?5a7ff87)
No.2ベストアンサー
- 回答日時:
そうなんですか^^ 失礼しました。
以下のコードを実行すると boost のライブラリで計算したもの、Ru-LaLaさんのコードで計算したもの、サンプル実装で計算したものを比較すると、Ru-LaLaさんので計算したものだけ値が違うので、Ru-LaLaさんのコードが間違ってる可能性があるような気がします^^;サンプルコードは、
http://page.freett.com/seaside/vip/crc/ProgramC1 …
から取りました。サンプルコードをパクってしまえばいいのでは?(笑)
====
#include <iostream>
#include <boost/crc.hpp>
unsigned short ProgCrc1(unsigned char* Data, unsigned long StartAdr, unsigned long StopAdr)
{ unsigned short vCRC; /*CRCを計算する変数*/
unsigned char vData; /*CRC計算時に1データ読み込む変数*/
/*初期化*/
vCRC = 0;
vData = 0;
/*CRC書き込み位置の初期化*/
*(Data + StopAdr + 1) = 0;
*(Data + StopAdr + 2) = 0;
/*CRC-ITU-Tの計算*/
for(unsigned long Loop1=StartAdr; Loop1<=StopAdr+2; Loop1++) /*CRC書き込み位置までループ*/
{ vData = *(Data + Loop1); /*1Byte読みこみ*/
/*CRC1Byte計算*/
for(char Loop2=0; Loop2<8; Loop2++)
{/*CRC計算変数がシフトで桁あふれするか確認*/
if((vCRC & 0x8000) != 0)
/*桁あふれ有り*/
{ vCRC = vCRC << 1; /*CRC計算変数1Bitシフト*/
vCRC = vCRC ^ 0x1021; /*生成多項式のXOR*/
}
else
/*桁あふれ無し*/
{ vCRC = vCRC << 1; /*CRC計算変数1Bitシフト*/
}
/*データ変数がシフトで桁あふれするか確認*/
if((vData & 0x80) != 0)
/*桁あふれ有り*/
{ vData = vData << 1; /*データ変数1Bitシフト*/
vCRC = vCRC ^ 0x0001; /*CRC計算変数に1XOR*/
}
else
/*桁あふれ無し*/
{ vData = vData << 1; /*データ変数1Bitシフト*/
}
}
}
*(Data + StopAdr + 2) = (unsigned char)(vCRC & 0x00ff); /*CRCの下位書き込み*/
*(Data + StopAdr + 1) = (unsigned char)((vCRC >> 8) & 0x00ff); /*CRCの上位書き込み*/
return(vCRC);
}
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);
}
unsigned short crc_itu_t(unsigned char *data, unsigned long num)
{
boost::crc_basic<16> calc(0x1021);
calc.process_bytes(data, num);
return static_cast<unsigned short>(calc.checksum());
}
int main()
{
unsigned char data[6 + 2] = { 'a', 'b', 'c', 'd', 'e', 'f' };
std::cout << std::showbase << std::hex;
std::cout << crc_itu_t(data, 6) << '\n';
std::cout << Crc(data, 6) << '\n';
std::cout << ProgCrc1(data, 0, 5) << '\n';
std::cout << static_cast<int>(data[6]) << '\n';
std::cout << static_cast<int>(data[7]) << '\n';
}
====
./a.exe
0x3afd
0x58e1
0x3afd
0x3a
0xfd
No.7
- 回答日時:
★昔買ったアルゴリズム事典より抜粋します。
サンプル:
#include <limits.h>
unsigned short crc( unsigned const char *pData, unsigned long lNum )
{
unsigned int crc16 = 0xFFFFU;
unsigned long i;
int j;
for ( i = 0 ; i < lNum ; i++ ){
crc16 ^= (unsigned int)pData[i] << (16 - CHAR_BIT);
for ( j = 0 ; j < CHAR_BIT ; j++ ){
if ( crc16 & 0x8000 ){
crc16 = (crc16 << 1) ^ 0x1021;
}
else{
crc16 <<= 1;
}
}
}
return (unsigned short)(~crc16);
}
その他:
・回答者 No.2 さんのリンクのソースでfor文の条件式が『Loop1<=StopAdr+2』となる理由が
良く分からないな?何で『StopAdr+2』に『+2』にしているの?不思議だ。どいう理由かな。
そもそも CRC-ITU-T って聞いた事が無い。CRC-CCITT なら聞いた事があります。
XOR している定数が 0x1021 だから多項式は x^16+x^12+x^5+x^0 となり CRC-CCITT だよな。
ネット検索したら『CRC-ITU-T』でヒットしたのでページを見たら多項式は同じだった。
http://page.freett.com/seaside/vip/crc/DocCRC.htm→『CRCの正体と種類』
もしかして『CRC-ITU-T』と『CRC-CCITT』は同じなのかな?→読んだら今は『ITU-T』だって。同じだ。
・アルゴリズム事典では『if ( vData & 0x80 ){ … }』の処理はないね。
この質問のソースを見たときに『あれ?何か?変?』と思った箇所だ。
もう良く分からないのでこれまで。ギブアップ!
・以上。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?5a7ff87)
No.6
- 回答日時:
うーーん。
。。Oh-Orange さんので試してみましたが、値がサンプルコードのものや boost のライブラリのものとは違いますね^^; どれが正しいのか読んでないのでわかりませんが、『あるものは使えばいい。壊れてないのに直すなよ(by ワインバーグ)』ってことで、サンプルコードをそのまま使うのがいいんじゃないでしょうか。。。No.5
- 回答日時:
★最初に。
>for(i = 0; i <= num; i++){
↑
for(i = 0; i < num; i++){
です。『<=』だと1バイト余分に計算しちゃいますよ。
『i』カウンタを使うよりはポインタを使ったら。
・下に書き直したソースを貼り付けて置きます。
サンプル:
unsigned short Crc( unsigned char *Data, unsigned long num )
{
unsigned short vCrc; //CRCを計算する変数
unsigned char vData;
int i;
for ( vCrc = 0 ; num > 0 ; num-- ){
vData = *Data++; //1byte読み込み
for ( i = 0 ; i < 8 ; i++ ){
vCrc <<= 1; //1bitシフト
vData <<= 1; //データ変数1bitシフト
//CRC計算変数がシフトで桁あふれする場合
if ( vCrc & 0x8000 ){
vCrc ^= 0x1021; //多項式とXOR
}
if ( vData & 0x80 ){
vCrc ^= 1; //CRC計算変数に1をXOR
}
}
}
return vCrc;
}
その他:
・次のリンクを元に CRC-CCITT を書き直すと左ローテートしないといけないみたいだよ。
http://www.wdic.org/w/WDIC/CRC→『CRC - 通信用語の基礎知識』
・テーブルを用いた CRC16 のソースが Vector さんのところにあります。
下の『参考URL』もどうぞ。
・以上。
参考URL:http://www.vector.co.jp/soft/dos/hardware/se0204 …
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?5a7ff87)
No.3
- 回答日時:
ん?ProgCrc1(data, 0, 5) で呼び出さないといけないのかな?すみません、Ru-LaLa さんのプログラムをきちんと読んでいないので^^; でも、
std::cout << ProgCrc1(data, 0, 5) << '\n';
としても、値が 0xcd50 になって、他ので計算した値とは違いました^^;
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?5a7ff87)
No.1
- 回答日時:
直接の回答ではないですが、特別なものでなければ、自分で作るより boost とかの CRC を使ったほうがいいんじゃないかと思います^^
http://boost.cppll.jp/HEAD/libs/crc/crc.html
早い回答ありがとうございます。
すみません、私はC言語初心者でして。
参考のURL先の内容を理解できません。
本当に、ごめんなさい。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- メルカリ メルカリでMovement in motion 腕時計 MIM-CRC-SSが新品未使用で7000円 1 2022/07/29 08:42
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Visual Basic(VBA) vba 等間隔の列に対しての計算 6 2022/05/17 20:15
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
16進数 加算 減算 C言語
-
”/”を使わずに割り算したいんで...
-
VB.net Double と...
-
c languageで 簡単な質問があ...
-
O(n log n)について2
-
ExcelのINT関数の計算結果がお...
-
距離から緯度経度を求める方法
-
色の判定
-
除算を使わずに10で割りたい。
-
引き算で端数が出る理由
-
【C言語】RGBと輝度の計算に関して
-
floatの有効桁数
-
三菱シーケンサ(Aシリーズ)で...
-
Excel VBAでの数値の計算につい...
-
数値計算で生じる小さなごみ
-
Visual Studioのバージョンによ...
-
EXCELの関数"STDEV(標準偏差)"...
-
スーパーコンピュータの処理速...
-
VBAでミリ秒まで出力する方法
-
java 実数の割り算
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
O(n log n)について2
-
16進数 加算 減算 C言語
-
c languageで 簡単な質問があ...
-
ExcelでPC(パソコン)によって...
-
”/”を使わずに割り算したいんで...
-
有効数字について 以前質問をし...
-
三角比の俯角の計算
-
ExcelのINT関数の計算結果がお...
-
VB.net Double と...
-
floatの有効桁数
-
パソコンで階乗を計算
-
三菱シーケンサ(Aシリーズ)で...
-
除算を使わずに10で割りたい。
-
VB6.0での小数点の扱いについて
-
EXCELの関数"STDEV(標準偏差)"...
-
時刻の比較
-
VBAでの割り算の余りの求め方
-
計算の丸め誤差の解消について
-
C言語プログラミングにて、arct...
-
VBAでミリ秒まで出力する方法
おすすめ情報