计算机基础 —— 海明码 (C++实现)


      海明码原理校验方法


前言

     海明(汉明)码是广泛采用的一种有效的校验码,它实际上是一种多重奇偶校验码。

     海明码的原理就是在有效信息位中加入几个校验位形成海明码,并把海明码的每一个二进制分配到几个奇偶校验中。当某一位出错的时候,不仅能检错,还能发现出错位的位置。假设校验位有k位,那么校验码最多有2k个,显然其中有一个校验码是正确的,那么就能校验出2k-1个错位。所以,如果能满足一个n位数n+k<=2k-1,则在理论上即可判断出哪一位数出错。

C++代码

     C++实现海明码如下代码,Vs2017编译通过。

#define JHM(value)  ((value==1||value==49)?1:(value==0||value==48)?0:0)

// 支持序列长度为:3~11位
char *TrickTest::TotalHMCodec(char *hm)
{
	if (!hm) { return nullptr; }

	// 计算k k^2≥k+n+1
	unsigned short hmLen = strlen(hm);
	if (hmLen <= 1) { return nullptr; }	
	unsigned short K = 0;
	if (hmLen <= 4)			{ K = 3; }
	else if (hmLen <= 11)	{ K = 4; }
	else if (hmLen <= 26)	{ K = 5; }
	else if (hmLen <= 26)	{ K = 5; }

	// 创建处理新字符串
	int *HM = new int[hmLen * sizeof(int)], *pHM = HM;
	memset(HM, 0, hmLen * sizeof(int));
	for (short index = hmLen - 1; index >= 0; *pHM++ = hm[index], --index);
	pHM = nullptr;

	// 构建表格
	const unsigned short tableLen = K + hmLen;
	char *tableBuf = new char[tableLen +1];
	memset(tableBuf, 0, tableLen+1);
	std::vector<unsigned short> nTmp;
	for (unsigned short index = 0; index < K; nTmp.push_back(pow(2, index)-1), ++index);

	// 表格填充
	pHM = HM;
	for (unsigned short index = 0; index < tableLen; ++index)
	{
		if (std::find(nTmp.begin(), nTmp.end(), index) == nTmp.end()) { tableBuf[index] = *pHM++; }
		else { tableBuf[index] = '-'; }
	}
	if (HM) { delete[]HM; }
	HM = pHM = nullptr;

	// 异或运算
	int *kBuf = new int[K * sizeof(int)];
	memset(kBuf, 0, K * sizeof(int));
	for (unsigned short index = 0; index < K; ++index)
	{
		if (index + 1 == 1)
		{
			if (tableLen == 5		|| tableLen == 6)	{ kBuf[index] = JHM((int)(tableBuf[2] ^ tableBuf[4])); }									// 6
			else if (tableLen == 7  || tableLen == 8)	{ kBuf[index] = JHM((int)(tableBuf[2] ^ tableBuf[4] ^ tableBuf[6])); }						// 7
			else if (tableLen == 9  || tableLen == 10)  { kBuf[index] = JHM((int)(tableBuf[2] ^ tableBuf[4] ^ tableBuf[6] ^ tableBuf[8])); }		// 9
			else if (tableLen == 11 || tableLen == 12)	{ kBuf[index] = JHM((int)(tableBuf[2] ^ tableBuf[4] ^ tableBuf[6] ^ tableBuf[8] ^ tableBuf[10])); }
		}
		else if (index + 1 == 2)
		{
			if (tableLen == 5)							{ kBuf[index] = JHM((int)(tableBuf[2])); }
			else if (tableLen == 6)						{ kBuf[index] = JHM((int)(tableBuf[5])); }													// 6
			else if (tableLen >= 7 && tableLen <= 9)	{ kBuf[index] = JHM((int)(tableBuf[5] ^ tableBuf[6])); }									// 7 9
			else if (tableLen == 10)					{ kBuf[index] = JHM((int)(tableBuf[2] ^ tableBuf[5] ^ tableBuf[6] ^ tableBuf[9])); }
			else if (tableLen == 11 || tableLen == 12)	{ kBuf[index] = JHM((int)(tableBuf[2] ^ tableBuf[5] ^ tableBuf[6] ^ tableBuf[9] ^ tableBuf[10])); }
		}
		else if (index + 1 == 3)
		{
			if (tableLen == 5)							{ kBuf[index] = JHM((int)(tableBuf[4])); }
			else if (tableLen == 6)						{ kBuf[index] = JHM((int)(tableBuf[4] ^ tableBuf[5])); }									// 6
			else if (tableLen >=7 && tableLen <=11)		{ kBuf[index] = JHM((int)(tableBuf[4] ^ tableBuf[5] ^ tableBuf[6]));}						// 7 9
			else if (tableLen == 12)					{ kBuf[index] = JHM((int)(tableBuf[4] ^ tableBuf[5] ^ tableBuf[6] ^ tableBuf[11])); }
		}
		else if (index + 1 == 4)
		{
			if (tableLen == 9)							{ kBuf[index] = JHM((int)(tableBuf[8]));}													// 9
			else if (tableLen == 10)					{ kBuf[index] = JHM((int)(tableBuf[8] ^ tableBuf[9])); }
			else if (tableLen == 11)					{ kBuf[index] = JHM((int)(tableBuf[8] ^ tableBuf[9] ^ tableBuf[10])); }
			else if (tableLen == 12)					{ kBuf[index] = JHM((int)(tableBuf[8] ^ tableBuf[9] ^ tableBuf[11] ^ tableBuf[11])); }
		}
	}

	// 填充完善
	if (K == 3 || K == 4)
	{
		tableBuf[0] = (char)(kBuf[0]+48);
		tableBuf[1] = (char)(kBuf[1]+48);
		tableBuf[3] = (char)(kBuf[2]+48);
		if (K == 4) { tableBuf[7] = (char)(kBuf[3] + 48); }
	}
	if (kBuf) { delete[]kBuf; }kBuf = nullptr;

	// 翻转
	for (unsigned short index = 0; index < tableLen / 2; ++index)
	{
		char tmp = tableBuf[index];
		tableBuf[index] = tableBuf[tableLen - 1 - index];
		tableBuf[tableLen - 1 - index] = tmp;
	}

	std::cout  << tableBuf;

	// 调用者需要释放
	return tableBuf;
}

关注

笔者 - jxd

微信公众号搜索 “码农总动员” 或 微信扫描下方二维码,了解更多你不知道的XX,O(∩_∩)O

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

信必诺

嗨,支持下哥们呗。

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

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

打赏作者

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

抵扣说明:

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

余额充值