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であることが問題解決の鍵だと思うのですが、何か問題点わかりますか?
No.2ベストアンサー
- 回答日時:
うまくいきません。
だけではなく、必ず同じ結果になるということに
着目したのは、まず、OKとしま
しょう。
「結果」というのは、直接的には、
crcReg[] の値です。
まず、crcReg[] の値を変化させて
いる(または設定している)箇所を
全て抜き出します。
1) crcReg[s]=0xFFFF;
2) crcReg[s] = crcReg[s] >> 1;
3) crcReg[s] = (crcReg[s] ^ 0x8408);
よく見ると、1) は、初期設定。
2) は、for(t = 0; t < 8; t++) の
ループで毎回実行されますから、
トータルで、8ビット右シフトが発生し
ここで、crcReg[] は、0x00ff に
なっていることがわかります。
そうすると、3) は、「一度も実行
されていない」ことが推定できます。
ここまでが第一段階。
次に行きます。
3) が一度も実行されていないというこ
とは、これを実行するための条件が
決して満足されないということです。
つまり、
if (flag == 0x01) が成立しない。
つまり、
flag = (crcReg[s] ^ jyuroku[s] & 0x01);
が 0x01 にならない。
ということがわかります。
結論から言えば、ここが今回問題点です。
& と ^ は演算子の優先順位が異なります。
(& の優先順位が高い)
従って、この式は、意図しない順序で計算
されます。
この結果、flag の上位桁には、crcReg[] の
(そもそも、0xffff で初期化された)値
がそのまま反映されてしまいます。
この結果、flga が 0x01 になることはない
というのが今回の結果になります。
そうすれば、
flag = ((crcReg[s] ^ jyuroku[s]) & 0x01);
とすれば少なくとも、「同じ結果」にはなら
ないことがわかると思います。
No.1
- 回答日時:
参考にしてください
static Word crctable[256];
void MakeCrc(void)
{
Word i;
Word j;
Word r;
for (i = 0; i < 256; i++) {
r = i;
for (j = 0; j < 8; j++)
if (r & 1)
r = (r >> 1) ^ 0x8408u;
else
r >>= 1;
crctable[i] = r;
}
}
Word GetCrcN(Byte *s, int len)
{
Word r;
r = 0xFFFFu;
while (len--) {
r = (r >> 8) ^ crctable[(Byte)r ^ *s++];
}
return (r ^ 0xFFFFu);
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10個出力で改行したいのですが...
-
strcmp
-
printf で二進表示を行いたい。
-
改行について 1行に何個かづ...
-
【C言語教えてください】sin波...
-
c言語でAからZまでを表示する...
-
C言語プログラミング
-
CTRL+Dでループを抜けるには
-
二つの整数値の大小比較
-
%P と %X の違い
-
scanfに文字が入力されたときに...
-
コマンドプロンプトがすぐ消える
-
C言語で、 printf()とwhile文を...
-
C言語
-
BMI値から体型を判定するプログ...
-
分数を表示するプログラム(長...
-
C言語で入力した変数の値から三...
-
ガウスの消去法、後退代入について
-
4の倍数を論理演算で表す。。
-
C言語について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語について
-
printf で二進表示を行いたい。
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
テキストカーソル位置の取得
-
strcmp
-
unsigned int型について
-
c言語でAからZまでを表示する...
-
printf( " %2d", p * q );
-
コマンドラインに出力した文字...
-
printfの出力内の文字をdefine...
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
小数点切捨て表示
-
【C言語教えてください】sin波...
-
switch分のケースを範囲数?に...
-
二つの整数値の大小比較
-
4の倍数を論理演算で表す。。
-
defineで定数が置き換えられな...
おすすめ情報