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 碼
2.bcd 轉ascii/* 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; }
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;
}