C言語関係掲示板

過去ログ

No878 CRC-32を求める

[戻る] [ホームページ]
No.11376

CRC-32
投稿者---れいが(2003/12/21 16:10:41)


れいがと申します。
現在CRC-32を求めようとしています。
CRC-32の演算結果だけではなく、
組み込み機器で使用するので演算ソースが必要となります。

他の掲示板で回答がえられなかったので、ここにやってきました。
他の掲示板でえた情報をもとに自分で理解し書き直してみました
が、思うような結果が得られません(正しいと思われるCRCが読み出せない)

以下に自分で書いたソースをのせます。
ご教授お願いいたします。

/********************************************************************************/
/* */
/* [関数名] make_crc_32_table */
/* */
/* [内容] CRC-32用テーブル作成 */
/* */
/* [引数] void */
/* */
/* [戻値] void */
/* */
/********************************************************************************/
void make_crc_32_table(void)
{
unsigned long i, j, k;

for(j = 0;j < 256;j++) {
i = j;
for(k = 0; k < 8; k++) {
if(i & 1) i = 0xedb88320L ^ (i >> 1);
else i = i >> 1;
}
Crc_32_Table[j] = i;
}
}


/********************************************************************************/
/* */
/* [関数名] calc_crc_32_2 */
/* */
/* [内容] CRC-32演算2 */
/* */
/* [引数] unsigned long n : 演算サイズ */
/* unsigned char *dat_ptr : 演算データ格納先ポインタ */
/* */
/* [戻値] unsigned long : CRC値 */
/* */
/********************************************************************************/
unsigned long calc_crc_32_2(unsigned long n,unsigned char *dat_ptr)
{
unsigned long crc;

crc = 0;
while(1){
if(!n) break;
crc = (crc >> 8) ^ Crc_32_Table[(crc ^ *dat_ptr) & 0xff];
dat_ptr++;
n--;
}
return(crc);
}




No.11381

Re:CRC-32
投稿者---RAPT(2003/12/21 20:45:54)


/*
「質問専用掲示板」も見たけど、コンパイル可能なソースコードを掲載してください。

お試しってことで、下記のPGと、3年前σ(^^)が書いたPGに食わせてみた。
エサは下記の内容が含まれているテキストファイル[A.txt]
-----ここから-----
20031028
19781223
20450112
19800512
-----ここまで-----
れいが産の:155701BA Windows2000/VC++6.0sp5
私のコード:612CDB61 Windows98/LSI-C86 3.30C試食版
であった。

私のコードは下記にて公開しているものをDLして確認できる
http://www.atmark.gr.jp/~s2000/rapt/freesoft/index.html#CRC_LZH

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned long g_Crc32_Table[257];

void init()
{
  unsigned long i, k, value;

  for(i = 0; i < 256; ++i){
    value = i;
    for(k = 0; k < 8; ++k){
      if(value & 1)
        value = 0xEDB88320L ^ (value >> 1);
      else
        value >>= 1;
    }
    g_Crc32_Table[i] = value;
  }
}


unsigned long calc(unsigned char *pData, unsigned long nCount)
{
  unsigned long crc = 0;
  size_t index;
  for(; nCount; --nCount){
    index = (crc ^ *pData) & 0xFF;
    crc = (crc >> 8) ^ g_Crc32_Table[index];
    ++pData;
  }
  return crc;
}


int main(int argc, char *argv[])
{
  FILE *fp = NULL;
  unsigned char buff[1+BUFSIZ] = {0};
  unsigned long crc, count;

  if (argc < 2){
    fprintf(stderr, "ファイル名を指定してください\n");
    exit(1);
  }
  if ((fp = fopen(argv[1], "rb")) == NULL){
    fprintf(stderr, "%s ファイルが開けません\n", argv[1]);
    exit(1);
  }
  fgets(buff, BUFSIZ, fp);
  fclose(fp);
  count = strlen(buff);

  init();
  crc = calc(buff, count);
  printf("String : [%s]\nCRC32 : [%X]\n", buff, crc);
  return 0;
}


No.11403

Re:CRC-32
投稿者---れいが(2003/12/22 17:30:59)


回答ありがとうございます。
実行してみたところ結果のCRC値が違うように思えます。

確認したいのですが、CRCとは
データ列:0x12345678
データ列のCRC:0x9ABCDEF0(仮にです)
とする場合に
0x123456789ABCDEF0のCRCが
0x0になることをいうんですよね?

No.11430

Re:CRC-32
投稿者---RAPT(2003/12/23 00:32:42)


>実行してみたところ結果のCRC値が違うように思えます。
参考までに。上記でσ(^^)が書いたのは、れいが産のコードをそのまま
使ったもので、σ(^^)が上記で正としたものは、σ(^^)の昔のコードです。

比較用にRAPT産とれいが産のコードによる実行結果比較できるコードを
用意してみました。

ご覧になっていただければ分かるかと思いますが、CRCコードの初期値と
最終処理のみの差です。


#include <stdio.h>
#include <stdlib.h>

unsigned long Crc_32_Table[257];
void make_crc_32_table(void)
{
  unsigned long i, j, k;

  for(j = 0; j < 256; ++j){
    i = j;
    for(k = 0; k < 8; ++k){
      if (i & 1)  i = 0xedb88320L ^ (i >> 1);
      else    i >>= 1;
    }
    Crc_32_Table[j] = i;
  }
}

int main(int argc, char *argv[])
{
  FILE *fp = NULL;
  char buff[10] = {0};
  unsigned long crc;
  int c;

  if (argc < 2){
    fprintf(stderr, "error - ファイル名を指定してください.\n");
    exit(1);
  }
  
  fp = fopen(argv[1], "rb");
  if(fp == NULL){
    fprintf(stderr, "error - %s ファイルが開けません.\n", argv[1]);
    exit(1);
  }

  make_crc_32_table();
  if (argc > 2){
    /* 引数2つだとこっち:最初に全ビットを立ててから計算→最後に反転 */
    crc = 0xffffffff;
    while ((c = getc(fp)) != EOF) {
      crc = (crc >> 8) ^ Crc_32_Table[(crc ^ c) & 0xff];
    }
    crc = ~crc;
    printf("RAPT産\n");
  }else{
    /* 引数1つだとこっち:最初に全ビットを0にしてから計算 */
    crc = 0;
    while ((c = getc(fp)) != EOF) {
      crc = (crc >> 8) ^ Crc_32_Table[(crc ^ c) & 0xff];
    }
    printf("れいが産\n");
  }

  fclose(fp);

  printf("File : %s\n", argv[1]);
  printf("CRC32: %08lX\n", crc);
  return 0;
}


No.11454

Re:CRC-32
投稿者---れいが(2003/12/25 14:36:37)


ちがいについては理解できたのですが、
やはり、実行結果が違うように思えます。
前回も確認させていただきましたが

> 確認したいのですが、CRCとは
> データ列:0x12345678
> データ列のCRC:0x9ABCDEF0(仮にです)
> とする場合に
> 0x123456789ABCDEF0のCRCが
> 0x0になることをいうんですよね?

でいいんですか?

No.11474

Re:CRC-32
投稿者---RAPT(2003/12/27 00:19:38)


残念ながら、詳しい事は知りません。
当時、「らるち〜」との互換性があることで動作確認OKと
みなすことにしたので(^^;

No.11510

Re:CRC-32
投稿者---れいが(2004/01/05 15:49:10)


わかりました。
ご協力ありがとうございました。
これ以降は他の掲示板に書き込んでみます。

No.11570

Re:CRC-32
投稿者---NykR(2004/01/08 13:32:15)


誘導

チャット式C言語 から来て VC++倶楽部へ行きました。