⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bint.cpp

📁 大数运算类,用于RSA算法,支持4096位二进制的数学运算
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************/
//大数运算库源文件:Bint.cpp
//作者:afanty@vip.sina.com
//版本:1.0 (2003.4.26)
//说明:适用于MFC
/****************************************************************/

#include "Bint.h"

//初始化类成员变量
void CBint::InitData()					
{	m_Sign=1;
	m_Length=1;
	m_InSystem=AUTO_SYSTEM;
	m_OutSystem=DEC_SYSTEM;
	ZeroMemory(m_Value,BI_MAXLEN*sizeof(unsigned long));
}

//初始化大数为0
CBint::CBint()
{	
	InitData();
}

CBint::CBint(const /*unsigned*/ __int64 Value)
{	
	InitData();
	SetValue(Value);
}

//重载的构造函数,初始化字符串
CBint::CBint(LPCSTR Value)
{	
	InitData();
	SetValue(CString(Value));
}

//重载的构造函数,初始化字符串类
CBint::CBint(const CString& Value)
{	
	InitData();
	SetValue(Value);
}

//重载的构造函数,初始化CBint类
CBint::CBint(const CBint& Value)
{	
	InitData();
	SetValue((CBint&)Value);
}

//采用缺省的解构函数
CBint::~CBint()
{
}

//大数比较
//调用形式 N.Compare(B)   返回N>B 如果大数N位数比大数B多,当然N>B
//如果位数相同,则从高位开始比较,直到分出大小
//	N > B 		返回 1
//	N == B		返回 0
//	N < B		返回 -1
int CBint::Compare(const CBint& B) const
{	if(m_Sign!=B.m_Sign)
	{	if(m_Sign)
			return 1;
		else
			return -1;
	}
	if(m_Length>B.m_Length)			//	1
		return (m_Sign==1?1:-1);
	if(m_Length<B.m_Length)			//	-1
		return (m_Sign==1?-1:1);
	for(int i=m_Length-1;i>=0;i--)
	{
		if(m_Value[i]>B.m_Value[i])
			return (m_Sign==1?1:-1);
		if(m_Value[i]<B.m_Value[i])
			return (m_Sign==1?-1:1);
	}
	return 0;
}

int CBint::Compare(long B) const
{	int Sign=B>=0?1:0;
	if(m_Sign!=Sign)
	{	if(m_Sign)
			return 1;
		else
			return -1;
	}
	if(m_Length>1)
		return (m_Sign==1?1:-1);
	if(m_Value[0]>(unsigned long)B)
		return (m_Sign==1?1:-1);
	if(m_Value[0]<(unsigned long)B)
		return (m_Sign==1?-1:1);
	return 0;
}
int CBint::CompareAbs(const CBint& B) const
{
	if(m_Length>B.m_Length)			//	1
		return 1;
	if(m_Length<B.m_Length)			//	-1
		return -1;
	for(int i=m_Length-1;i>=0;i--)
	{
		if(m_Value[i]>B.m_Value[i])
			return 1;
		if(m_Value[i]<B.m_Value[i])
			return -1;
	}
	return 0;
}
int CBint::CompareAbs(unsigned long B) const
{	if(m_Length>1)
		return 1;
	if(m_Value[0]>B)
		return 1;
	if(m_Value[0]<B)
		return -1;
	return 0;
}
//照搬参数的各属性
CBint& CBint::SetValue(const CBint& Src)
{	m_Length=Src.m_Length;
	m_Sign=Src.m_Sign;
	m_InSystem=((CBint &)Src).InSystem();
	m_OutSystem=((CBint&)Src).OutSystem();
	CopyMemory(m_Value,Src.m_Value,BI_MAXLEN*sizeof(unsigned long));
	return *this;
}

CBint& CBint::SetValue(const /*unsigned*/ __int64 intSrc)
{	__int64 tmp=intSrc;
	if(tmp<0) tmp=-tmp;
	ZeroMemory(m_Value,BI_MAXLEN*sizeof(unsigned long));
	//m_Sign=1;
	m_Sign=(intSrc<0?0:1);
	m_Length=1;
	m_Value[0]=(unsigned long)tmp;
	if(intSrc>0xffffffff)
	{	m_Length=2;
		m_Value[1]=(unsigned long)(intSrc>>32);
	}
	return *this;
}

CBint& CBint::SetValue(const CString& szSrc)
{	int system=m_InSystem,len=szSrc.GetLength();
	register int Index=0,k=0;
	SetValue(0);
	if(len>0)
	{
		if(system==AUTO_SYSTEM)
		{	system=DEC_SYSTEM;
			CString x(szSrc.Left(2));
			x.MakeLower();
			if(x =="0x" || x=="&h")
			{
				system=HEX_SYSTEM;
				Index=2;
			}
			else if(x=="&o")
			{
				system=OCT_SYSTEM;
				Index=2;
			}
			else if(x=="&b")
			{	
				system=BIN_SYSTEM;
				Index=2;
			}
			else if(x=="&o")
			{	
				system=OCT_SYSTEM;
				Index=2;
			}
			else
			{	for(k=0;k<len;k++)
				{
					if((szSrc[k]>='A' && szSrc[k]<='F') || (szSrc[k]>='a' && szSrc[k]<='f'))
					{	system=HEX_SYSTEM;
						break;
					}
				}
			}
			switch(szSrc[len-1])			//通过后缀确定输入字符的进制
			{	case 'o':					//8进制输入
				case 'O':
					system=OCT_SYSTEM;
					break;
				case 'h':					//16进制输入
				case 'H':
					system=HEX_SYSTEM;
					break;
			}
		}

		if(len>0 && szSrc[0]=='-')
		{	Index=1;
			m_Sign=0;
		}
		for(; Index<len; Index++)
		{	k=szSrc[Index];
			switch(system)
			{	case BIN_SYSTEM:
					if(k!='0' && k!='1')
						continue;
					k-='0';
					break;
				case OCT_SYSTEM:
					if(k<'0' || k>'7')
						continue;
					k-='0';
					break;
				case DEC_SYSTEM:
					if(k<'0' || k>'9')
						continue;
					k-='0';
					break;
				case HEX_SYSTEM:
					if(k>='0' && k<='9')
						k-='0';
					else if(k>='A' && k<='F')
						k-='A'-10;
					else if(k>='a' && k<='f')
						k-='a'-10;
					else
						continue;
					break;
				default:
					continue;
			}
			//SetValue(Mul(system));
			//SetValue(Add(k));
			*this=Mul(system).Add(k);
		}
	}
	if(m_Length==1 && m_Value[0]==0)
		m_Sign=1;
	return *this;
}

//重载=操作符
CBint& CBint::operator = (const /*unsigned*/ __int64 intSrc)
{
	return SetValue(intSrc);
}

CBint& CBint::operator =(const CString& szSrc)
{
	return SetValue(szSrc);
}

CBint& CBint::operator = (LPCSTR lpSrc)
{
	return SetValue(CString(lpSrc));
}

CBint::operator CString() const
{	CString str("");
	char ch,Mask[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
	CBint X(*this);
	while(X.m_Value[X.m_Length-1]>0)
	{	ch=Mask[X.ModAbs(m_OutSystem)];
		str.Insert(0,ch);
		X.SetValue(X.Div(m_OutSystem));
	}
	if(!m_Sign)
	{
		str.Insert (0,"-");
	}
	if(str.GetLength()==0)
		str.Insert(0,"0");
	return str;
}

unsigned long CBint::operator[](int nIndex) const
{	if(nIndex<0 || nIndex>m_Length-1) nIndex=0;
	return m_Value[m_Length-nIndex-1];
}

//大数相加 
//调用形式: N.Add(B) 返回 N+B 
//	若两大数符号相等,其值相加,否则,改变被加数符号,再调用N-B,即 N+(-B)
/******************************************************************/
/*
例如:
     A  B  C
+       D  E
--------------
= S  F  G  H

其中,若C+E<=0xffffffff,则H=C+E,carry(进位标志)=0
     若C+E>0xffffffff,则H=C+E-0x100000000,carry=1

     若B+D+carry<=0xfffffff,则G=B+D,carry=0      
     若B+D+carry>0xfffffff,则G=B+D+carry-0x10000000,carry=1

     若carry=0,则F=A,S=0
     若carry=1,A<0xfffffff,则F=A+1,S=0
     若carry=1,A=0xfffffff,则F=0,S=1
/*****************************************************************/
CBint CBint::Add(const CBint& B) const
{	CBint N(B);
	register unsigned int carry=0;
	unsigned __int64 sum=0;
	if(m_Sign==N.m_Sign)
	{	if(N.m_Length<m_Length)
			N.m_Length=m_Length;
		for(register int i=0;i<N.m_Length;i++)
		{
			sum=(unsigned __int64)N.m_Value[i]+m_Value[i]+carry;
			N.m_Value[i]=(unsigned long)sum;
			carry=sum>0xFFFFFFFF?1:0;
		}
		if(N.m_Length<BI_MAXLEN)
		{	N.m_Value[N.m_Length]=carry;
			N.m_Length+=carry;
		}
	}
	else
	{	N.m_Sign=m_Sign;
		//return ((CBint*)this)->Sub(N);
		int cmp=CompareAbs(B);
		if(cmp)
		{	int len;
			unsigned long *Small,*Bigger;
			if(cmp>0)
			{
				Bigger=(unsigned long*)m_Value;
				Small=(unsigned long*)B.m_Value;
				len=m_Length;
			}
			if(cmp<0)
			{ 
				Bigger=(unsigned long*)B.m_Value;
				Small=(unsigned long*)m_Value;
				len=B.m_Length;
				N.m_Sign=1-N.m_Sign;
			}
			for(register int i=0;i<len;i++)
			{	if((Bigger[i]-carry)>=Small[i])
				{
					N.m_Value[i]=Bigger[i]-carry-Small[i];
					carry=0;
				}
				else
				{
					sum=0x100000000+Bigger[i];
					N.m_Value[i]=(unsigned long)(sum-carry-Small[i]);
					carry=1;
				}
			}
			while(N.m_Value[len-1]==0)
				len--;
			N.m_Length=len;
		}
		else
			N.SetValue(0);
	}
	return N;
}

CBint CBint::Add(long B) const
{	CBint N(*this);
	if(B==0)
		return N;
	if((m_Sign*B)>=0)
	{	unsigned __int64 sum;
	    sum=(unsigned __int64)B+N.m_Value[0];
		N.m_Value[0]=(unsigned long)sum;
		if(sum>0xffffffff)
		{	register int i=1;
			while(i<BI_MAXLEN && N.m_Value[i]==0xffffffff)
			{	N.m_Value[i]=0;
				i++;
			}
			N.m_Value[i]++;
			if(i<BI_MAXLEN)
				N.m_Length=i+1;
		}
		return N;
	}
	else
		return N.Sub(-B);
}


//大数相减
//调用形式:N.Sub(B),返回值:N-B
//若两大数符号相同,其值相减,否则改变参数符号再调用大数相加函数
/******************************************************************/
/*
例如:
     A  B  C
-       D  E
--------------
=    F  G  H

其中,若C>=E,则H=C-E,carry(借位标志)=0
     若C<E,则H=C-E+0x100000000,carry=1

     若B-carry>=D,则G=B-carry-D,carry=0      
     若B-carry<D,则G=B-carry-D+0x10000000,carry=1

     若carry=0,则F=A
     若carry=1,A>1,则F=A-1
     若carry=1,A=1,则F=0
/*****************************************************************/
CBint CBint::Sub(const CBint& B) const
{	CBint N(*this);
	if(m_Sign==B.m_Sign)
	{	int cmp=N.CompareAbs(B); 
		if(cmp)
		{	int len,carry=0;
			unsigned __int64 num;
			unsigned long *Bigger,*Small;
			if(cmp>0)
			{
				Bigger=(unsigned long*)N.m_Value;
				Small=(unsigned long*)B.m_Value;
				len=N.m_Length;
			}
			if(cmp<0)
			{ 
				Bigger=(unsigned long*)B.m_Value;
				Small=(unsigned long*)N.m_Value;
				len=B.m_Length;
				N.m_Sign=1-N.m_Sign;
			}
			for(register int i=0;i<len;i++)
			{	if((Bigger[i]-carry)>=Small[i])
				{
					N.m_Value[i]=Bigger[i]-carry-Small[i];
					carry=0;
				}
				else
				{
					num=0x100000000+Bigger[i];
					N.m_Value[i]=(unsigned long)(num-carry-Small[i]);
					carry=1;
				}
			}
			while(len>1 && N.m_Value[len-1]==0)
				len--;
			N.m_Length=len;
		}
		else
			N.SetValue(0);
		return N;
	}
	else
	{	int cmp=N.CompareAbs(B); 
		if(cmp)
		{	if(N.m_Length<B.m_Length)
				N.m_Length=B.m_Length;
			unsigned __int64 sum;
			int carry=0;
			for(register int i=0;i<N.m_Length;i++)
			{
				sum=(unsigned __int64)N.m_Value[i]+B.m_Value[i]+carry;
				N.m_Value[i]=(unsigned long)sum;
				carry=sum>0xFFFFFFFF?1:0;
			}
			if(N.m_Length<BI_MAXLEN)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -