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

📄 biginteger.cs

📁 Granados是一个基于.NET的SSH客户端库。同时支持SSH1和SSH2。实现了AES, Blowfish, TripleDES, RSA, DSA等加密验证算法。实现TCP协议连接。
💻 CS
📖 第 1 页 / 共 5 页
字号:

                // take the absolute value of the inputs
                try
                {
                        if((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative
                        {
                                bi1Neg = true; bi1 = -bi1;
                        }
                        if((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative
                        {
                                bi2Neg = true; bi2 = -bi2;
                        }
                }
                catch(Exception) {}

                BigInteger result = new BigInteger();

                // multiply the absolute values
                try
                {
                        for(int i = 0; i < bi1.dataLength; i++)
                        {
                                if(bi1.data[i] == 0)    continue;

                                ulong mcarry = 0;
                                for(int j = 0, k = i; j < bi2.dataLength; j++, k++)
                                {
                                        // k = i + j
                                        ulong val = ((ulong)bi1.data[i] * (ulong)bi2.data[j]) +
                                                     (ulong)result.data[k] + mcarry;

                                        result.data[k] = (uint)(val & 0xFFFFFFFF);
			                mcarry = (val >> 32);
                                }

                                if(mcarry != 0)
                                        result.data[i+bi2.dataLength] = (uint)mcarry;
                        }
                }
                catch(Exception)
                {
                        throw(new ArithmeticException("Multiplication overflow."));
                }


                result.dataLength = bi1.dataLength + bi2.dataLength;
                if(result.dataLength > maxLength)
                        result.dataLength = maxLength;

                while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
                        result.dataLength--;

                // overflow check (result is -ve)
                if((result.data[lastPos] & 0x80000000) != 0)
                {
                        if(bi1Neg != bi2Neg && result.data[lastPos] == 0x80000000)    // different sign
                        {
                                // handle the special case where multiplication produces
                                // a max negative number in 2's complement.

                                if(result.dataLength == 1)
                                        return result;
                                else
                                {
                                        bool isMaxNeg = true;
                                        for(int i = 0; i < result.dataLength - 1 && isMaxNeg; i++)
                                        {
                                                if(result.data[i] != 0)
                                                        isMaxNeg = false;
                                        }

                                        if(isMaxNeg)
                                                return result;
                                }
                        }

                        throw(new ArithmeticException("Multiplication overflow."));
                }

                // if input has different signs, then result is -ve
                if(bi1Neg != bi2Neg)
                        return -result;

                return result;
        }



        //***********************************************************************
        // Overloading of unary << operators
        //***********************************************************************

        public static BigInteger operator <<(BigInteger bi1, int shiftVal)
        {
                BigInteger result = new BigInteger(bi1);
                result.dataLength = shiftLeft(result.data, shiftVal);

                return result;
        }


        // least significant bits at lower part of buffer

        private static int shiftLeft(uint[] buffer, int shiftVal)
        {
                int shiftAmount = 32;
                int bufLen = buffer.Length;

                while(bufLen > 1 && buffer[bufLen-1] == 0)
                        bufLen--;

                for(int count = shiftVal; count > 0;)
                {
                        if(count < shiftAmount)
                                shiftAmount = count;

                        //Console.WriteLine("shiftAmount = {0}", shiftAmount);

                        ulong carry = 0;
                        for(int i = 0; i < bufLen; i++)
                        {
                                ulong val = ((ulong)buffer[i]) << shiftAmount;
                                val |= carry;

                                buffer[i] = (uint)(val & 0xFFFFFFFF);
                                carry = val >> 32;
                        }

                        if(carry != 0)
                        {
                                if(bufLen + 1 <= buffer.Length)
                                {
                                        buffer[bufLen] = (uint)carry;
                                        bufLen++;
                                }
                        }
                        count -= shiftAmount;
                }
                return bufLen;
        }


        //***********************************************************************
        // Overloading of unary >> operators
        //***********************************************************************

        public static BigInteger operator >>(BigInteger bi1, int shiftVal)
        {
                BigInteger result = new BigInteger(bi1);
                result.dataLength = shiftRight(result.data, shiftVal);


                if((bi1.data[maxLength-1] & 0x80000000) != 0) // negative
                {
                        for(int i = maxLength - 1; i >= result.dataLength; i--)
                                result.data[i] = 0xFFFFFFFF;

                        uint mask = 0x80000000;
                        for(int i = 0; i < 32; i++)
                        {
                                if((result.data[result.dataLength-1] & mask) != 0)
                                        break;

                                result.data[result.dataLength-1] |= mask;
                                mask >>= 1;
                        }
                        result.dataLength = maxLength;
                }

                return result;
        }


        private static int shiftRight(uint[] buffer, int shiftVal)
        {
                int shiftAmount = 32;
                int invShift = 0;
                int bufLen = buffer.Length;

                while(bufLen > 1 && buffer[bufLen-1] == 0)
                        bufLen--;

                //Console.WriteLine("bufLen = " + bufLen + " buffer.Length = " + buffer.Length);

                for(int count = shiftVal; count > 0;)
                {
                        if(count < shiftAmount)
                        {
                                shiftAmount = count;
                                invShift = 32 - shiftAmount;
                        }

                        //Console.WriteLine("shiftAmount = {0}", shiftAmount);

                        ulong carry = 0;
                        for(int i = bufLen - 1; i >= 0; i--)
                        {
                                ulong val = ((ulong)buffer[i]) >> shiftAmount;
                                val |= carry;

                                carry = ((ulong)buffer[i]) << invShift;
                                buffer[i] = (uint)(val);
                        }

                        count -= shiftAmount;
                }

                while(bufLen > 1 && buffer[bufLen-1] == 0)
                        bufLen--;

                return bufLen;
        }


        //***********************************************************************
        // Overloading of the NOT operator (1's complement)
        //***********************************************************************

        public static BigInteger operator ~(BigInteger bi1)
        {
                BigInteger result = new BigInteger(bi1);

                for(int i = 0; i < maxLength; i++)
                        result.data[i] = (uint)(~(bi1.data[i]));

                result.dataLength = maxLength;

                while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
                        result.dataLength--;

                return result;
        }


        //***********************************************************************
        // Overloading of the NEGATE operator (2's complement)
        //***********************************************************************

        public static BigInteger operator -(BigInteger bi1)
        {
                // handle neg of zero separately since it'll cause an overflow
                // if we proceed.

                if(bi1.dataLength == 1 && bi1.data[0] == 0)
                        return (new BigInteger());

                BigInteger result = new BigInteger(bi1);

                // 1's complement
                for(int i = 0; i < maxLength; i++)
                        result.data[i] = (uint)(~(bi1.data[i]));

                // add one to result of 1's complement
                long val, carry = 1;
                int index = 0;

                while(carry != 0 && index < maxLength)
                {
                        val = (long)(result.data[index]);
                        val++;

                        result.data[index] = (uint)(val & 0xFFFFFFFF);
                        carry = val >> 32;

                        index++;
                }

                if((bi1.data[maxLength-1] & 0x80000000) == (result.data[maxLength-1] & 0x80000000))
                        throw (new ArithmeticException("Overflow in negation.\n"));

                result.dataLength = maxLength;

                while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
                        result.dataLength--;
                return result;
        }


        //***********************************************************************
        // Overloading of equality operator
        //***********************************************************************

        public static bool operator ==(BigInteger bi1, BigInteger bi2)
        {
			if(Object.Equals(bi1, bi2))
				return true;
			else
				return bi1.Equals(bi2);
        }


        public static bool operator !=(BigInteger bi1, BigInteger bi2)
        {
			if(Object.Equals(bi1, bi2))
				return false;
			else
				return !(bi1.Equals(bi2));
        }


        public override bool Equals(object o)
        {
				if(o==null || !(o is BigInteger)) return false;
				BigInteger bi = (BigInteger)o;

                if(this.dataLength != bi.dataLength)
                        return false;

                for(int i = 0; i < this.dataLength; i++)
                {
                        if(this.data[i] != bi.data[i])
                                return false;
                }
                return true;
        }


        public override int GetHashCode()
        {
                return this.ToString().GetHashCode();
        }


        //***********************************************************************
        // Overloading of inequality operator
        //***********************************************************************

        public static bool operator >(BigInteger bi1, BigInteger bi2)
        {
        	int pos = maxLength - 1;

        	// bi1 is negative, bi2 is positive
        	if((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0)
        	        return false;

                // bi1 is positive, bi2 is negative
        	else if((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0)
        	        return true;

                // same sign
        	int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;

⌨️ 快捷键说明

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