c语言 ascii 和 压缩bcd 码之间的相互转换

转载请标注出处:(版权所有)

本文将从五点详细介绍bcd码和ascii 之间的关系,如下所示:

一、简介

二、用途

三、特点

四、代码原理

五、代码

       1、ascii 转压缩bcd码   2、 压缩bcd 转ascii 码

六、总结语

正文

一、简介

   (1) bcd 码(仅0-9)

bcd 二-十进制代码(Binary Coded Decimal):主要采用 4 位 表示一个十进制(通常一个字节只取低四位),常见的有8421码,如:0100 为4 范围为: 0-9 。 321则是:0011 0010 0001

(2) ascii 码

标准的ascii码值范围为 0-127 最高位为0,128-255为拓展的ascii码 例如由IBM自拓展的图形。

(3)压缩的bcd 码(包含 A-F)

由于bcd 码取低四个字节,导致高四个字节空闲没有,因此可以将十进制的两个字节压缩成1个字节 如 “32” 则为0x32

二、用途

(1)金额等仅数字的压缩

(2)表示发送内容的长度压缩

三、特点

1.有损压缩:  bcd 仅取后四个字节进行压缩,因此还原也仅低四位

2. 任意字符压缩: 本文代码是对任意字符进行压缩仅取后四位。(压缩bcd 仅用于0-9 A-F之间)

四、代码原理

        0:0000    '0'  0011 0000   
1:0001    '1'  0011 0001      'A' 0100 0001'a' 0110 0001
2:0010    '2'  0011 0010      'B' 0100 0010'b' 0110 0010
3:0011 ~~~~              ‘C' 0100 0011'c' 0110 0011
4:0100 ~~~~ ~~~~ ~~~~
5:0101 ~~~~ ~~~~ ~~~~
6:0110 ~~~~ ~~~~ ~~~~
7:   0111 ~~~~ ~~~~ ~~~~
8:1000 ~~~~ ~~~~ ~~~~
9:   1001 ~~~~ ~~~~~~~~

其中 0-9 A-F a-f第四个字节是一样的。所以可以根据后四个字节进行压缩和还原

五、代码

1.ascii 转bcd 码

/*
nType  0 左靠右边补0  1 有靠左边补0
*/
int AscToBcd(const unsigned char *pszAscStr,int nLen, int nType, unsigned char *pszBcdStr)
{
	unsigned char *psTempbuf = (unsigned char *)pszAscStr;
	int nBcdCount = 0;
	int nIcount = 0;
	int nAsciiLen = 0;
	int nIsDouble = 0;//是否为双
	if(pszAscStr == NULL || pszBcdStr == NULL)
		return APP_FAIL;
	nAsciiLen =	strlen((char *)pszAscStr);
	if(nAsciiLen < nLen)
		nLen = nAsciiLen;
	else
		nAsciiLen = nLen; //否则长度为原来的
	//判断单双  8421 所有除了第一位外所有相加都为偶数
	if(nLen&0x01 == 1)
	{
		nIsDouble = 0;//奇数
		nAsciiLen = nLen -1;
		//判断靠的方向
		if(nType == 1) //向右边
		{
			nIcount = 1;
			nAsciiLen ++;//补齐回去
		}
		
	}
	else
	{
		nIsDouble = 1;

	}
	for (nBcdCount = nIcount; nIcount < nAsciiLen; nIcount ++,nBcdCount++)
	{
		if (
			(psTempbuf[nIcount] >= 'A' && 	psTempbuf[nIcount] <= 'F' )||
			(psTempbuf[nIcount] >= 'a' && 	psTempbuf[nIcount] <= 'f' )
		   )
		{
			pszBcdStr[nBcdCount] = (int)(psTempbuf[nIcount++] & 0x0f) +9;

		}
		else
		{
			pszBcdStr[nBcdCount] = (int)(psTempbuf[nIcount++] & 0x0f);
		}

		if (
			(psTempbuf[nIcount] >= 'A' && 	psTempbuf[nIcount] <= 'F' )||
			(psTempbuf[nIcount] >= 'a' && 	psTempbuf[nIcount] <= 'f' )
			)
		{
			pszBcdStr[nBcdCount] = (((int)pszBcdStr[nBcdCount]) << 4) | ((int)(psTempbuf[nIcount] & 0x0f) +9);
			
		}
		else
		{
			pszBcdStr[nBcdCount] = (((int)pszBcdStr[nBcdCount]) << 4) | ((int)(psTempbuf[nIcount] & 0x0f));
		}
	
	}
	if (nIsDouble == 0)
	{
		if(nType == 1) //向右边
		{
			if (
				(pszAscStr[0] >= 'A' && 	pszAscStr[0] <= 'F' )||
				(pszAscStr[0] >= 'a' && 	pszAscStr[0] <= 'f' )
			)
			{

					pszBcdStr[0] = (int)(psTempbuf[0] & 0x0f) +9;
			}
			else
			{

				pszBcdStr[0] = (int)(psTempbuf[0] & 0x0f) ;
			}
		
		}
		else //左靠
		{
			if (
				(pszAscStr[nIcount] >= 'A' && 	pszAscStr[nIcount] <= 'F' )||
				(pszAscStr[nIcount] >= 'a' && 	pszAscStr[nIcount] <= 'f' )
				)
			{
				
				pszBcdStr[nBcdCount] = (int)(psTempbuf[nIcount] & 0x0f) +9;
			}
			else
			{
				
				pszBcdStr[nBcdCount] = (int)(psTempbuf[nIcount] & 0x0f) ;
			}
			pszBcdStr[nBcdCount] = 	pszBcdStr[nBcdCount] << 4;//左移动

		}
	}
	return APP_SUCCESS;
}
2.bcd 转ascii

int BcdToAsc(const unsigned char *pszBcdStr,int nLen, int nType, unsigned char *pszAscStr)
{
	unsigned char *psTempbuf = (unsigned char *)pszBcdStr;
	int nHight = 0;//高四位
	int nLow = 0;//第四位
	int nIcount = 0;
	int nAsciiLen = 0;
	int nIsDouble = 0;//是否为双
	if(pszAscStr == NULL || pszBcdStr == NULL)
		return APP_FAIL;

	//判断单双  8421 所有除了第一位外所有相加都为偶数
	if(nLen&0x01 == 1) //3
	{
		nIsDouble = 0;//奇数
		//判断靠的方向
		if(nType == 1) //向右边
		{
			nIcount = 1;
			
		}
		else
		{

			nLen --;//左边对齐
		}
		
	}
	else
	{
		nIsDouble = 1;
		
	}
	for (nAsciiLen = nIcount; nAsciiLen < nLen; nIcount ++)
	{

		nHight = (int)(pszBcdStr[nIcount])>>4;
		nLow = (int)(pszBcdStr[nIcount])&0x0f;
	
		if ( nHight > 9 && nHight < 16 )
		{
			pszAscStr[nAsciiLen ++] = nHight + 'A' -10; 
		}
		else
		{
			pszAscStr[nAsciiLen ++] = nHight + '0' -0; 
		}
		if ( nLow > 9 && nLow < 16 )
		{
			pszAscStr[nAsciiLen ++] = nLow + 'A' -10; 
		}
		else
		{
			pszAscStr[nAsciiLen ++] = nLow + '0' -0; 
		}

	}
	if (nIsDouble == 0)
	{
		if(nType == 1) //向右边
		{
		
			nLow = (int)(pszBcdStr[0])&0x0f;
		
			if ( nLow > 9 && nLow < 16 )
			{
				pszAscStr[0 ] = nLow + 'A' -10; 
			}
			else
			{
				pszAscStr[0] = nLow + '0' -0; 
			}

			
		}
		else //左靠
		{
			
			
			nHight = (int)(pszBcdStr[nIcount])>>4;
			
			if ( nHight > 9 && nHight < 16 )
			{
				pszAscStr[nAsciiLen ] = nHight + 'A' -10; 
			}
			else
			{
				pszAscStr[nAsciiLen ] = nHight + '0' -0; 
			}
		}
		
	}
	return APP_SUCCESS;
}

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值