1. 程式人生 > >c語言 ascii 和 壓縮bcd 碼之間的相互轉換

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;
}