我是靠谱客的博主 潇洒河马,最近开发中收集的这篇文章主要介绍fcs 校验和计算 以太网帧CRC校验 C语言,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

#define alt_8    char  
#define alt_u8   unsigned char  
#define alt_32   int  
#define alt_u32  unsigned int  
#define alt_64   long long  
#define alt_u64  unsigned long long  

//位翻转函数  
alt_u64 Reflect(alt_u64 ref, alt_u8 ch)
{
int i;
alt_u64 value = 0;
for (i = 1; i < (ch + 1); i++)
{
if (ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
}
return value;
}

//标准的CRC32多项式  
#define poly  0x04C11DB7  
//翻转的CRC32多项式  
#define upoly 0xEDB88320  

alt_u32 crc32_bit(alt_u8 *ptr, alt_u32 len, alt_u32 gx)
{
alt_u8 i;
alt_u32 crc = 0xffffffff;
while (len--)
{
for (i = 1; i != 0; i <<= 1)
{
if ((crc & 0x80000000) != 0)
{
crc <<= 1;
crc ^= gx;
}
else
crc <<= 1;
if ((*ptr & i) != 0)
crc ^= gx;
}
ptr++;
}
return (Reflect(crc, 32) ^ 0xffffffff);
}

alt_u32 Table1[256];
alt_u32 Table2[256];

// 生成CRC32 普通表 , 第二项是04C11DB7  
void gen_direct_table(alt_u32 *table)
{
alt_u32 gx = 0x04c11db7;
unsigned long i32, j32;
unsigned long nData32;
unsigned long nAccum32;
for (i32 = 0; i32 < 256; i32++)
{
nData32 = (unsigned long)(i32 << 24);
nAccum32 = 0;
for (j32 = 0; j32 < 8; j32++)
{
if ((nData32 ^ nAccum32) & 0x80000000)
nAccum32 = (nAccum32 << 1) ^ gx;
else
nAccum32 <<= 1;
nData32 <<= 1;
}
table[i32] = nAccum32;
}
}

// 生成CRC32 翻转表 第二项是77073096  
void gen_normal_table(alt_u32 *table)
{
alt_u32 gx = 0x04c11db7;
alt_u32 temp, crc;
for (int i = 0; i <= 0xFF; i++)
{
temp = Reflect(i, 8);
table[i] = temp << 24;
for (int j = 0; j < 8; j++)
{
unsigned long int t1, t2;
unsigned long int flag = table[i] & 0x80000000;
t1 = (table[i] << 1);
if (flag == 0)
t2 = 0;
else
t2 = gx;
table[i] = t1^t2;
}
crc = table[i];
table[i] = Reflect(table[i], 32);
}
}

alt_u32 DIRECT_TABLE_CRC(alt_u8 *ptr, int len, alt_u32 * table)
{
alt_u32 crc = 0xffffffff;
alt_u8 *p = ptr;
int i;
for (i = 0; i < len; i++)
crc = (crc << 8) ^ table[(crc >> 24) ^ (alt_u8)Reflect((*(p + i)), 8)];
return ~(alt_u32)Reflect(crc, 32);
}

alt_u32 Reverse_Table_CRC(alt_u8 *data, alt_32 len, alt_u32 * table)
{
alt_u32 crc = 0xffffffff;
alt_u8 *p = data;
int i;
for (i = 0; i <len; i++)
crc = table[(crc ^ (*(p + i))) & 0xff] ^ (crc >> 8);
return  ~crc;
}

//这是一个完整的以太网帧。最后四个字节 8b 6b f5 13是其FCS字段,用于与后面生成的CRC32对照  
alt_u8  tx_data[] = {
0xff,   0xff,   0xff,   0xff,   0xff,   0xff,   0x00,   0x1f,   //8  
0x29,   0x00,   0xb5,   0xfa,   0x08,   0x06,   0x00,   0x01,   //15  
0x08,   0x00,   0x06,   0x04,   0x00,   0x01,   0x00,   0x1f,   //24  
0x29,   0x00,   0xb5,   0xfa,   0xac,   0x15,   0x0e,   0xd9,   //32  
0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0xac,   0x15,   //40  
0x0e,   0x8e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   //48  
0x00,   0x00 ,  0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   //56  
0x00,   0x00,   0x00,   0x00,   0x8b,   0x6b,   0xf5,   0x13    //64  
};

int main()
{
alt_u8 *data = tx_data;
alt_u32 dataLen = sizeof(tx_data) - 4;


int sum = 256;

int i = 0;


//生成普通表,用于直接计算的表  
gen_direct_table(Table1);
printf("Table1 :n");
for (i = 0; i < sum; i++)
{
if (i<16)
printf("%08x ", Table1[i]);
}
printf("nn");

//生成翻转表,是官方推荐的,故称其为normal_table  
gen_normal_table(Table2);
printf("Table2 :n");
for (i = 0; i < sum; i++)
{
if (i<16)
printf("%08x ", Table2[i]);
}
printf("nn");

printf("dataLen = %dn", dataLen);//打印数据长度,应该是60字节。  

 //计算并打印出CRC32校验码,应该是0x13f56b8b  

                                                                          //按照bit进行校验,最慢  

printf("Slow CRC by bit          : %08xn", crc32_bit(data, dataLen, 0x04c11db7));
//使用普通表,非官方,很慢  
printf("Direct Table  ref + xor  : %08xn", DIRECT_TABLE_CRC(data, dataLen, Table1));
//使用翻转表,官方推荐的,很快  
printf("Reverse Table  ref + xor : %08xn", Reverse_Table_CRC(data, dataLen, Table2));

system("pause");
return 0;
}

最后

以上就是潇洒河马为你收集整理的fcs 校验和计算 以太网帧CRC校验 C语言的全部内容,希望文章能够帮你解决fcs 校验和计算 以太网帧CRC校验 C语言所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部