位操作奇偶校验算法

本文详细介绍了四种计算数据比特位奇偶校验的方法:方法一是通过与1按位操作计数;方法二是利用取模和整除操作;方法三是通过逐位与减一操作;方法四是使用预定义的奇偶校验表。这些方法有助于开发者检测数据传输中的错误。
摘要由CSDN通过智能技术生成

目录

前言

一、方法一

二、方法二

三、方法三

四、方法四


前言

信息的传输都是以比特流的方式传输的,数据在传输过程中,可能存在传输错误的情况,如发送的数据是01001101,而接收到的数据是01001100,比特位出现最低位出现错误,由1变成了0。为了检测出这种错误,工程应用上通常采用奇偶校验的方式来实现。

以奇校验为例,我们传输的一个字节8比特的数据,先计算比特位1的个数,如果比特位1的个数是奇数,则第9位设置为0,如果比特位1的个数是偶数,则第9位设置为1,连续9比特的1的个数始终保持奇数。偶校验类似。

本文档主要描述计算比特位奇偶数量的方法,供开发者参考。

一、方法一

任何数字的某个比特位与1进行与操作,对应比特位结果为1,则表明比特位是1,利用这个特点,将这个数字的二进制与1进行按位与,然后将数字右移以为重复操作,最终计算出比特位1的个数。

int parity_method1(char data)
{
	int i;
	int n = sizeof(char);
	int count = 0;

	for (i = 0; i < n; i++)
	{
		if ((data & 1) == 1)
		{
			count++;
		}
		data = data >> 1;
	}

	return (count % 2);  //偶数返回0,奇数返回1
}

二、方法二

举例推理,若一个数字346,对它每个位进行%10、/10操作,因为一个数%10的余数是<10,如下:

346 % 10 = 6

346 /10 = 34

34%10 = 4

34/10=3

如此,如果我们进行%2、/2操作,数字取模2的结果是1,则改为为1,依次可以计算出数字的1 的个数。

int parity_method2(unsigned char data)
{
	int i = 0;
	int n = sizeof(char);
	int count = 0;

	for(i = 0; i < n; i++)
	{ 
		if (data % 2 == 1)
		{
			count++;
		}
		data = (data>>1);
	}
	return (count % 2);  //偶数返回0,奇数返回1
}

三、方法三

一个数字与上这个数字减一的数,该数二进制最右边的1必然会消除掉,以此类推,从右往左,每一次进行按位与操作,都会取消掉一个1,直到该数字变为0,跳出循环,就得到了该数字二进制中1的个数。

int parity_method3(unsigned char data)
{
	int i = 0;
	int n = sizeof(unsigned char);
	int count = 0;

	while (data != 0)
	{
		data = data & (data - 1);
		count++;
	}
	return (count % 2);  //偶数返回0,奇数返回1
}

四、方法四

#define P2(N) N,N^1,N^1,N
#define P4(N) P2(N),P2(N^1),P2(N^1),P2(N)
#define P6(N) P4(N),P4(N^1),P4(N^1),P4(N)
static const bool parity_table[256] = {P6(0),P6(1),P6(1),P6(0)}; //偶数个1parity_table[i]=0,否则parity_table[i]=1
int main(void)
{
	unsigned char data = 6;
	int result = 0;
	result = parity_table[data & 0xff];
	printf("result = %d\r\n",result);
	if ( result == 0)
	{
		printf("偶数个1\r\n");
	}
	else
	{
		printf("奇数个1");
	}
	return 0;
}

而对于32-bit的数,则使用下面的代码:

unsigned int v;

v ^= v >> 16;

v ^= v >> 8;bool parity = ParityTable256[v & 0xff];

原理:

(1)通过v^=v>>16,将v中的低16位与高16位进行按位或(^)操作, 相当于0~16位保留1的总个数的奇偶与v中的1的总  个数的奇偶相同;

(2)通过v^=v>>8,将v中的9~16位与0~8位进行按位或(^)操作,相当于0~8位保留1的总个数的奇偶与0~16中1的总个数的奇偶相同;

(3)通过(1)(2)操作,最初v中1的总个数的奇偶与最后v中1~8位中1的总个数的奇偶相同,v&0xff相当于获取v中1~8比特位的1,然后再查表即可。

或者使用如下的代码:

unsigned char * p = (unsigned char *) &v;

parity = ParityTable256[p[0] ^ p[1] ^ p[2] ^ p[3]];

原理:取v的地址,并进行强制类型转换为char*,

通过p[0] ^ p[1] ^ p[2] ^ p[3]] 操作,将p[i]中的所有的1都放在一个8位的数中,然后查表即可。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小草xyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值