A. 什麼是CRC碼
CRC是什麼東西呢?其實滲畢亂我們大家都不叢檔應該會對它陌生,回憶一下?你用過RAR和ZIP等壓縮軟體嗎?它數顫們是不是常常會給你一個惱人的「CRC校驗錯誤」信息呢?我想你應該明白了吧,CRC就是塊數據的計算值,它的全稱是「Cyclic Rendancy Check」,中文名是「循環冗餘碼」,「CRC校驗」就是「循環冗餘校驗
B. CRC原理簡介
最近剛好有時間,整理了一下關於CRC的資料,詳細對比了下程序的實現過程和原理,當然,高手都是不在意的。
本文主要介紹CRC的一些基礎知識,個人收獲是後面關於網上標准Demo程序的一些詳細解析。見下一篇https://www.jianshu.com/p/c0d93c2e89ce
聲明:本文定義部分參考網上多處資料,只是為了方便做個筆記,引用網文做一些更改,如有雷同鍵並塵,請私信說明並修改。
一、關於CRC的介紹
CRC即循環冗餘校驗碼(Cyclic Rendancy Check):數據通信領域中最常用的一種差錯校驗碼,其信息欄位和校驗欄位長度可以任意指定,但要求通信雙方定義的CRC標准一致。
二、工作原理
對於工控領域,我們主要利用CRC校驗來處理各種數據流的數據正確性校驗。
CRC原理 :在K位信息碼(目標發送數據)後再拼接R位校驗碼,使整個編碼長度為N位,因此這種編碼也叫(N,K)碼。通俗的說,就是在需要發送的信息後面附加一個數(即校驗碼),生成一個新的發送數據發送給接收端。這個數據要求能夠使生成的新數據被一個特定的數整除。這里的整除需要引入模 2除法的概念,附上網路關於模2計算的鏈接:
https://ke..com/item/模2運算/18556715?fr=aladdin
那麼,CRC校驗的具體做法就是
(1)選定一個標准除數(K位二進制數據串)
(2)在要發送的數據(m位)後面加上K-1位0,然後將這個新數(M+K-1位)以模2除法的方式除以上面這個標准除數,所得到的余數也就是該數據的CRC校驗碼(註:余數必須比除數少且只少一位,不夠就補0)
(3)將這個校驗碼附在原蔽埋m位數據後面,構成新的M+K-1位數據,發送給接收端。
(4)接收端將接收到的數據除以標准除數,如果余數為0則認為數據正確。
注意: CRC校驗中有兩個關鍵點:一是要預稿禪先確定一個發送端和接收端都用來作為除數的二進制比特串(或多項式);二是把原始幀與上面選定的除進行二進制除法運算,計算出FCS。前者可以隨機選擇,也可按國際上通行的標准選擇,但最高位和最低位必須均為「1」
實例:對於數據10110011(16#B3),以指定除數110011求它的CRC校驗碼,其過程如下:
關於校驗碼的計算(重點來了)
單純談CRC的模2除法其實並不困難,但實際計算中經常會遇到計算出來的結果和實際不一致的情況,這也是這幾天我在看的東西。
這里需要知道幾個組成部分或者說計算概念:多項式公式、多項式簡記式、數據寬度、初始值、結果異或值、輸入值反轉、輸出值反轉、參數模型。
1、多項式公式
對於CRC標准除數,一般使用多項式(或二項式)公式表示,如上例中除數11011的二項式為G(X)=X4+X3+X+1,X的指數就代表了該bit位上的數據為1,(最低位為0)。這里特別注意一下位數問題,除數的位數為二項式最高次冪+1(4+1=5),這個很重要。
2、多項式簡記式
通過對CRC的基本了解我們知道,多項式的首尾必定為1,而這個1的位置在下一步計算一定為0,所以就把前面這個1給省略掉了,出現了一個叫簡記式的東西,如上例中除數11011的簡記式為1011,很多看過CRC高級語言源碼的人會知道,對於CRC_16標准下G(X)=X16+X15+X2+1(16#18005)的poly值實際上是8005,這里使用的就是簡記式。後面會對這個用法做一個說明。
3、數據寬度
數據寬度指的就是CRC校驗碼的長度(二進制位數),知道了CRC的運算概念和多項式,就可以理解這個概念了,CRC長度始終要比除數位數少1,與簡記式長度是一致的。
以上三個數據就是我們經常能夠用到的基本數據
4、初始值與結果異或值
在一些標准中,規定了初始值,則數據在進行上述二項式運算之前,需要先將要計算的數據與初始值的最低位元組進行異或,然後再與多項式進行計算。
而在結果異或值不為零的情況下,則需要將計算得到的CRC結果值再與結果異或值進行一次異或計算,得到的最終值才是我們需要的CRC校驗碼。
這里可以看出,初始值與結果值的位數要求與數據寬度一致。
5、輸入值反轉與輸出值反轉
輸入值反轉的意思是在計算之前先將二項式反轉,然後再用得到的新值和數據進行計算。如對於G(X)=X16+X15+X2+1(16#18005),其正向值為1 1000 0000 0000 0101,反轉值則為1010 0000 0000 0001 1
輸出值反轉則是將最終得到的CRC結果反轉。
通常,輸入值反轉後的結果值也會是反轉的,所以這兩個選項一般是同向的,我們只有在在線CRC計算器中會看到自由選擇正反轉的情況存在。
那麼,這里引用CSDN博主 bobde163 的一段總結:
CRC16、CRC32等多位元組的校驗值的計算有幾點需要清楚(只針對一次一個位元組的演算法):
1) 初始值不為0的情況下,該如何計算:
輸入數據需要反轉:先將要計算的數據與初始值的最低位元組進行異或,再與反轉後的多項式進行計算。
輸入數據不需要反轉:先將要計算的數據左移到與初始值對齊的位置(如CRC16演算法,則左移8位,低位填充0;如CRC32演算法,則左移24位,低位填充0)與初始值進行異或,再與正常的多項式進行計算。
2) 結果異或值不為0的情況:第一步算得到的CRC值再與結果異或值進行異或操作得到最終的校驗值:
輸出數據反轉:如果輸入數據是反轉的模式,則結果也是反轉的
輸出數據不反轉:如果輸入數據是不反轉的模式,則結果也是不反轉的
3)初始值的選擇是可自己定義,很多不同的廠家使用的初始值是不一樣,不一樣的初始值得到的結果也是不一樣的。
---------------------
原文:https://blog.csdn.net/bobde163/article/details/78760213
不同的二項式、初始值、結果異或值、反轉原則都會造成最終的結果不一致,這就是為什麼明明是正確的計算方式,有時候算出來的結果卻總是不正確。
那麼,如何去判斷應該採用哪些原則呢?這里談到最後一個概念:
6、參數模型
雖然CRC可以任意定義二項式、數據長度等,但沒有一個統一的標準的話,就會讓整個計算變得非常的麻煩。但實際上,不同的廠家經常採用不同的標准演算法,這里列出了一些國際常用的模型表:
以上為關於CRC的筆記,下一篇講一講高級語言實現思路
C. crc是什麼意思
CRC意思是循環冗餘碼校驗。
校驗原理:(M-R)/G=Q+0/G
說明:以接收到的校驗碼除以約定的除數,若余數為0,則可認為接收到的數據是正確的。
例:有效信息1101,生成多項式樣1011
循環校驗碼解:
有效信息1101(k=4),即M(x)=x3+x2+x0,生成多項式1011(r+1=4,即r=3);
即G(x)=x3+x1+x0,M(x)·x3=x6+x5+x3,即1101000(對1101左移三位);
M(x)·x3/G(x)=1101000/1011=1111+001/1011即1010的CRC是:1101001。
CRC碼集選擇的原則:
若設碼字長度為N,信息欄位為K位,校驗欄位為R位(N=K+R),則對於CRC碼集中的任一碼字,存在且僅存在一個R次多項式g(x),使得
V(x)=A(x)g(x)=xRm(x)+r(x);
其中:m(x)為K次信息多項式,r(x)為R-1次校驗多項式,
g(x)稱為生成多項式:
g(x)=g0+g1x+g2x2+。。。+g(R-1)x(R-1)+gRxR
發送方通過指定的g(x)產生CRC碼字,接收方則通過該g(x)來驗證收到的CRC碼字。
D. crc是什麼意思
CRC(Cyclic Rendancy Check),即循環冗餘校核,是一種根據網路數據包或電腦文件等數據產生簡短固定位數校核碼的快速演算法,主要用來檢測或校核數據傳輸或者保存後可能出現的錯誤。CRC利用除法及余數的原理,實現錯誤偵測的功能,具有原理清晰、實現簡單等優點。
CRC也就是循環冗餘校驗碼,是計算機網路通信領域常用的校驗碼。循環冗餘校驗碼包括一系列移位、相除等數據編碼規則,其演算法原理、演算法程序的設計與分析,都可以通過相應的軟體編碼進行解決。
循環冗餘校驗碼是利用軟體進行校驗的演算法,因此其檢驗速度很快,校驗的誤碼率也較低,整個計算機網路通信的信息傳輸速度很高。CRC差錯糾正控製法能夠有效減少通信線路的誤碼率,得到的通信數據傳旦友輸信息更准確。
在數據的傳輸過程中由於空間電磁環境復雜等原因,可能會產生誤碼,即某幾位數據0變為1,或1變為0,導致接收端得到錯誤的數據。為了降低誤碼率,通常對數據進行特定編碼,在收發端進行額外的驗證,使接收端能發現某些錯誤;
進而實現糾錯功能,常用的編碼方法有CRC-32校驗碼、CRC-16校驗碼、漢明碼、奇偶校驗法等。其中32位循環冗餘校驗簡稱CRC-32校驗在性能和資源消耗兩方面都有較大的優勢,因而,在無線電通信、旁正SATA硬碟數據傳輸等系統中,CRC-32校驗是運遲悔最常用的檢錯手段之一。
E. 簡化版的crc校驗,求翻譯成易語言源碼
.版本 2
.子程序 crc, 整數型
.參數 InData, 文本型
.參數 length, 整數型, 可空, 此參數可以不要,改為局部變數
.局部變數 num1, 整數型
.局部變數衫森 i, 整數型
.局部變數 bin, 位元組集
.局部變數 j_length, 整數型
bin = 到頃塌山位元組集 (InData)
j_length = 取位元組集長度 (bin)
.計次循環首 (j_length, i)
num1 = num1 + bin [i]
.計次循雀中環尾 ()
返回 (num1 % 50 + 48)
F. CRC指的是什麼
CRC:循環冗餘校驗(Cyclic Rendancy Check, CRC)。
CRC是一種根據網路數據包或電腦文件等數據產生簡短固定位數校驗碼的一種散列函數,主要用來檢測或校驗數據傳輸或者保存後可能出現的錯誤。它是利用除法及余數的原理來作錯誤偵測的。
CRC簡介:
在數據傳輸過程中,無論傳輸系統的設計再怎麼完美,差錯總會存在,這種差錯可能會導致在鏈路上傳輸的一個或者多個幀被破壞頃銀(出現比特差錯,0變為1,或者1變為0),從而接受方接收到錯誤的數據。
為盡量提高接受方收到數據的正確率,在接收方接收數據之前需要對數據進行差錯檢測,當且僅當檢測的結果為正確時接收方才真正收下數據。檢測的方式有多種,常見的有奇偶校驗、網際網路校驗和循環冗餘校驗等。
(6)crc的源碼是什麼擴展閱讀:
CRC應用場合:
CRC校驗實用程序庫 在數據存儲和數據通訊領域,為了保證數據的正確,就不得不採用檢錯的手段。在諸多檢錯手段中,CRC是最著名的一種。
CRC的全稱是循環冗餘校驗,其特點是:檢錯能力強,開銷小,易於用編碼器及檢測電路實現。從其檢錯能力來看,它所不能發現的錯誤的幾率僅為0.0047%以下。從性能森乎賣上和開銷上考慮,均遠遠優於奇偶校驗及算術和校驗等方式。
因而,在數據存儲和數據通訊此逗領域,CRC無處不在:著名的通訊協議X.25的FCS(幀檢錯序列)採用的是CRC-CCITT,WinRAR、NERO、ARJ、LHA等壓縮工具軟體採用的是CRC32,磁碟驅動器的讀寫採用了CRC16,通用的圖像存儲格式GIF、TIFF等也都用CRC作為檢錯手段。下面介紹硬體生成與計算CRC的過程。
參考資料:網路---CRC
G. CRC碼是什麼
循環冗餘校驗碼(CRC)
CRC校驗採用多項式編碼方法。被處理的數據塊可以看作是一個n階的二進制多項式,由
。如一個8位二進制數10110101可以表示為:
。多項式乘除法運算過程與普通代數多項式的乘除法相同。多項式的加減法運算以2為模,加減時不進,錯位,和邏輯異或運算一致。
採用CRC校驗時,發送方和接收方用同一個生成多項式g(x),並且g(x)的首位和最後一位的系數必須為1。CRC的處理方法是:發送方以g(x)去除t(x),得到余數作為CRC校驗碼。校驗時,以計算的校正結果是否為0為據,判斷數據幀是否出錯。
CRC校驗可以100%地檢測出所有奇數個隨機錯誤和長度小於等於k(k為g(x)的階數)的突發錯誤。所以CRC的生成多項式的階數越高,那麼誤判的概率就越小。CCITT建議:2048
kbit/s的PCM基群設備採用CRC-4方案,使用的CRC校驗碼生成多項式g(x)=
。採用16位CRC校驗,可以保證在
bit碼元中只含有一位未被檢測出的錯誤
。在IBM的同步數據鏈路控制規程SDLC的幀校驗序列FCS中,使用CRC-16,其生成多項式g(x)=
;而在CCITT推薦的高級數據鏈路控制規程HDLC的幀校驗序列FCS中,使用CCITT-16,其生成多項式g(x)=
。CRC-32的生成多項式g(x)=
。CRC-32出錯的概率比CRC-16低
倍
。由於CRC-32的可靠性,把CRC-32用於重要數據傳輸十分合適,所以在通信、計算機等領域運用十分廣泛。在一些UART通信控制晶元(如MC6582、Intel8273和Z80-SIO)內,都採用了CRC校驗碼進行差錯控制;乙太網卡晶元、MPEG解碼晶元中,也採用CRC-32進行差錯控制。
H. CRC碼的編碼和解碼程序是什麼
我有一個別人變得CRC程序,其中有好幾種CRC的編碼方法,也許會有用
using System;
namespace Communication.IO.Tools
{
/// <summary>
/// Tool to calculate and add CRC codes to a string
///
/// ***************************************************************************
/// Copyright (c) 2003 Thoraxcentrum, Erasmus MC, The Netherlands.
///
/// Written by Marcel de Wijs with help from a lot of others,
/則謹// especially Stefan Nelwan
///
/閉遲// This code is for free. I ported it from several different sources to C#.
///
/// For comments: [email protected]
/// ***************************************************************************
/// </summary>
public class CRCTool
{
// 'order' [1..32] is the CRC polynom order, counted without the leading '1' bit
// 'polynom' is the CRC polynom without leading '1' bit
//孫態基 'direct' [0,1] specifies the kind of algorithm: 1=direct, no augmented zero bits
// 'crcinit' is the initial CRC value belonging to that algorithm
// 'crcxor' is the final XOR value
// 'refin' [0,1] specifies if a data byte is reflected before processing (UART) or not
// 'refout' [0,1] specifies if the CRC will be reflected before XOR
// Data character string
// For CRC-CCITT : order = 16, direct=1, poly=0x1021, CRCinit = 0xFFFF, crcxor=0; refin =0, refout=0
// For CRC16: order = 16, direct=1, poly=0x8005, CRCinit = 0x0, crcxor=0x0; refin =1, refout=1
// For CRC32: order = 32, direct=1, poly=0x4c11db7, CRCinit = 0xFFFFFFFF, crcxor=0xFFFFFFFF; refin =1, refout=1
// Default : CRC-CCITT
private int order = 16;
private ulong polynom = 0x1021;
private int direct = 1;
private ulong crcinit = 0xFFFF;
private ulong crcxor = 0x0;
private int refin = 0;
private int refout = 0;
private ulong crcmask;
private ulong crchighbit;
private ulong crcinit_direct;
private ulong crcinit_nondirect;
private ulong [] crctab = new ulong[256];
// Enumeration used in the init function to specify which CRC algorithm to use
public enum CRCCode{CRC_CCITT, CRC16, CRC32};
public CRCTool()
{
//
// TODO: Add constructor logic here
//
}
public void Init(CRCCode CodingType)
{
switch( CodingType )
{
case CRCCode.CRC_CCITT:
order = 16; direct=1; polynom=0x1021; crcinit = 0xFFFF; crcxor=0; refin =0; refout=0;
break;
case CRCCode.CRC16:
order = 16; direct=1; polynom=0x8005; crcinit = 0x0; crcxor=0x0; refin =1; refout=1;
break;
case CRCCode.CRC32:
order = 32; direct=1; polynom=0x4c11db7; crcinit = 0xFFFFFFFF; crcxor=0xFFFFFFFF; refin =1; refout=1;
break;
}
// Initialize all variables for seeding and builing based upon the given coding type
// at first, compute constant bit masks for whole CRC and CRC high bit
crcmask = ((((ulong)1<<(order-1))-1)<<1)|1;
crchighbit = (ulong)1<<(order-1);
// generate lookup table
generate_crc_table();
ulong bit, crc;
int i;
if ( direct == 0 )
{
crcinit_nondirect = crcinit;
crc = crcinit;
for (i=0; i<order; i++)
{
bit = crc & crchighbit;
crc<<= 1;
if ( bit != 0 )
{
crc^= polynom;
}
}
crc&= crcmask;
crcinit_direct = crc;
}
else
{
crcinit_direct = crcinit;
crc = crcinit;
for (i=0; i<order; i++)
{
bit = crc & 1;
if (bit != 0)
{
crc^= polynom;
}
crc >>= 1;
if (bit != 0)
{
crc|= crchighbit;
}
}
crcinit_nondirect = crc;
}
}
/// <summary>
/// 4 ways to calculate the crc checksum. If you have to do a lot of encoding
/// you should use the table functions. Since they use precalculated values, which
/// saves some calculating.
/// </summary>.
public ulong crctablefast (byte[] p)
{
// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
// only usable with polynom orders of 8, 16, 24 or 32.
ulong crc = crcinit_direct;
if ( refin != 0 )
{
crc = reflect(crc, order);
}
if ( refin == 0 )
{
for ( int i = 0; i < p.Length; i++ )
{
crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^ p[i]];
}
}
else
{
for ( int i = 0; i < p.Length; i++ )
{
crc = (crc >> 8) ^ crctab[ (crc & 0xff) ^ p[i]];
}
}
if ( (refout^refin) != 0 )
{
crc = reflect(crc, order);
}
crc^= crcxor;
crc&= crcmask;
return(crc);
}
public ulong crctable (byte[] p)
{
// normal lookup table algorithm with augmented zero bytes.
// only usable with polynom orders of 8, 16, 24 or 32.
ulong crc = crcinit_nondirect;
if ( refin != 0 )
{
crc = reflect(crc, order);
}
if ( refin == 0 )
{
for ( int i = 0; i < p.Length; i++ )
{
crc = ((crc << 8) | p[i]) ^ crctab[ (crc >> (order-8)) & 0xff ];
}
}
else
{
for ( int i = 0; i < p.Length; i++ )
{
crc = (ulong)(( (int)(crc >> 8) | (p[i] << (order-8))) ^ (int)crctab[ crc & 0xff ]);
}
}
if ( refin == 0 )
{
for ( int i = 0; i < order/8; i++ )
{
crc = (crc << 8) ^ crctab[ (crc >> (order-8)) & 0xff];
}
}
else
{
for ( int i = 0; i < order/8; i++ )
{
crc = (crc >> 8) ^ crctab[crc & 0xff];
}
}
if ( (refout^refin) != 0 )
{
crc = reflect(crc, order);
}
crc^= crcxor;
crc&= crcmask;
return(crc);
}
public ulong crcbitbybit(byte[] p)
{
// bit by bit algorithm with augmented zero bytes.
// does not use lookup table, suited for polynom orders between 1...32.
int i;
ulong j, c, bit;
ulong crc = crcinit_nondirect;
for (i=0; i<p.Length; i++)
{
c = (ulong)p[i];
if ( refin != 0 )
{
c = reflect(c, 8);
}
for (j=0x80; j != 0; j>>=1)
{
bit = crc & crchighbit;
crc<<= 1;
if ( (c & j) != 0)
{
crc|= 1;
}
if ( bit != 0 )
{
crc^= polynom;
}
}
}
for ( i=0; (int)i < order; i++)
{
bit = crc & crchighbit;
crc<<= 1;
if ( bit != 0 ) crc^= polynom;
}
if ( refout != 0 )
{
crc=reflect(crc, order);
}
crc^= crcxor;
crc&= crcmask;
return(crc);
}
public ulong crcbitbybitfast(byte[] p)
{
// fast bit by bit algorithm without augmented zero bytes.
// does not use lookup table, suited for polynom orders between 1...32.
int i;
ulong j, c, bit;
ulong crc = crcinit_direct;
for (i = 0; i < p.Length; i++)
{
c = (ulong)p[i];
if ( refin != 0)
{
c = reflect(c, 8);
}
for ( j = 0x80; j > 0; j >>= 1 )
{
bit = crc & crchighbit;
crc <<= 1;
if ( (c & j) > 0 ) bit^= crchighbit;
if ( bit > 0 ) crc^= polynom;
}
}
if ( refout > 0)
{
crc=reflect( crc, order );
}
crc^= crcxor;
crc&= crcmask;
return(crc);
}
/// <summary>
/// CalcCRCITT is an algorithm found on the web for calculating the CRCITT checksum
/// It is included to demonstrate that although it looks different it is the same
/// routine as the crcbitbybit* functions. But it is optimized and preconfigured for CRCITT.
/// </summary>
public ushort CalcCRCITT(byte[] p)
{
uint uiCRCITTSum = 0xFFFF;
uint uiByteValue;
for (int iBufferIndex = 0; iBufferIndex < p.Length; iBufferIndex++)
{
uiByteValue = ( (uint) p[iBufferIndex] << 8);
for ( int iBitIndex = 0; iBitIndex < 8; iBitIndex++ )
{
if ( ( (uiCRCITTSum^uiByteValue) & 0x8000) != 0 )
{
uiCRCITTSum = (uiCRCITTSum <<1 ) ^ 0x1021;
}
else
{
uiCRCITTSum <<= 1;
}
uiByteValue <<=1;
}
}
return (ushort)uiCRCITTSum;
}
#region subroutines
private ulong reflect (ulong crc, int bitnum)
{
// reflects the lower 'bitnum' bits of 'crc'
ulong i, j=1, crcout = 0;
for ( i = (ulong)1 <<(bitnum-1); i != 0; i>>=1)
{
if ( ( crc & i ) != 0 )
{
crcout |= j;
}
j<<= 1;
}
return (crcout);
}
private void generate_crc_table()
{
// make CRC lookup table used by table algorithms
int i, j;
ulong bit, crc;
for (i=0; i<256; i++)
{
crc=(ulong)i;
if (refin != 0) // 'refin' [0,1] specifies if a data byte is reflected before processing (UART) or not
{
crc=reflect(crc, 8);
}
crc<<= order-8;
for (j=0; j<8; j++)
{
bit = crc & crchighbit;
crc<<= 1;
if ( bit !=0 ) crc^= polynom;
}
if (refin != 0)
{
crc = reflect(crc, order);
}
crc&= crcmask;
crctab[i]= crc;
}
}
#endregion
}
}
I. CRC校驗是什麼
CRC校驗碼:是數據通信領域中最常用的一種查錯校驗碼,其特徵是信息欄位和校驗欄位的長度可以任意選定。循環冗餘檢查(CRC)是一種數據傳輸檢錯功能。
可以對數據進行多項式計算,並將得到的結果附在幀的後面,接收設備也執行類似的演算法,以保證數據傳輸的正確性和完整性。
CRC校驗中有兩個關鍵點,一是預先確定一個發送送端和接收端都用來作為除數的二進制比特碼沒串(或多項式),可以遲核納隨機選擇,也可以使用國際標准。
但是最高位和最低位必須為1;二是把原始幀與上面計算出的除數進行模2除法運算,計氏純算出CRC碼。
J. 求一個CRC校驗C++源代碼。題目:發送數據為1101011011,生成的多項式為P(X)=X4+X+1(X4為X的4次方),
下面的代碼輸入為原數據和多項式對就飢薯的二進制碼,輸出為產生的校驗碼。
如原數據是1101011011,多項式是X^4+X+1(即10011)。產生的校驗碼為1110。
輸入110101101110011
輸出1110
#include<iostream>
#include<cstring>
#include<iomanip>
usingnamespacestd;
#defineWORDSIZE255
intgetNum(chara[],intn);
voidshowNum(intr,intn);
intmain(intargc,char*argv[])
{
cout<<"pleaseinputXandP:"<<endl;
intx,p,lenA,lenP;
chara[WORDSIZE];
memset(a,'