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

📄 biginteger.cs

📁 Granados是一个基于.NET的SSH客户端库。同时支持SSH1和SSH2。实现了AES, Blowfish, TripleDES, RSA, DSA等加密验证算法。实现TCP协议连接。
💻 CS
📖 第 1 页 / 共 5 页
字号:
	        for(pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos--);

	        if(pos >= 0)
	        {
		        if(bi1.data[pos] > bi2.data[pos])
			        return true;
		        return false;
	        }
	        return false;
        }


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

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

        	// same sign
        	int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;
	        for(pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos--);

	        if(pos >= 0)
	        {
		        if(bi1.data[pos] < bi2.data[pos])
			        return true;
		        return false;
	        }
	        return false;
        }


        public static bool operator >=(BigInteger bi1, BigInteger bi2)
        {
                return (bi1 == bi2 || bi1 > bi2);
        }


        public static bool operator <=(BigInteger bi1, BigInteger bi2)
        {
                return (bi1 == bi2 || bi1 < bi2);
        }


        //***********************************************************************
        // Private function that supports the division of two numbers with
        // a divisor that has more than 1 digit.
        //
        // Algorithm taken from [1]
        //***********************************************************************

        private static void multiByteDivide(BigInteger bi1, BigInteger bi2,
                                            BigInteger outQuotient, BigInteger outRemainder)
        {
                uint[] result = new uint[maxLength];

                int remainderLen = bi1.dataLength + 1;
                uint[] remainder = new uint[remainderLen];

                uint mask = 0x80000000;
                uint val = bi2.data[bi2.dataLength - 1];
                int shift = 0, resultPos = 0;

                while(mask != 0 && (val & mask) == 0)
                {
                        shift++; mask >>= 1;
                }

                //Console.WriteLine("shift = {0}", shift);
                //Console.WriteLine("Before bi1 Len = {0}, bi2 Len = {1}", bi1.dataLength, bi2.dataLength);

                for(int i = 0; i < bi1.dataLength; i++)
                        remainder[i] = bi1.data[i];
                shiftLeft(remainder, shift);
                bi2 = bi2 << shift;

                /*
                Console.WriteLine("bi1 Len = {0}, bi2 Len = {1}", bi1.dataLength, bi2.dataLength);
                Console.WriteLine("dividend = " + bi1 + "\ndivisor = " + bi2);
                for(int q = remainderLen - 1; q >= 0; q--)
                        Console.Write("{0:x2}", remainder[q]);
                Console.WriteLine();
                */

                int j = remainderLen - bi2.dataLength;
                int pos = remainderLen - 1;

                ulong firstDivisorByte = bi2.data[bi2.dataLength-1];
                ulong secondDivisorByte = bi2.data[bi2.dataLength-2];

                int divisorLen = bi2.dataLength + 1;
                uint[] dividendPart = new uint[divisorLen];

                while(j > 0)
                {
                        ulong dividend = ((ulong)remainder[pos] << 32) + (ulong)remainder[pos-1];
                        //Console.WriteLine("dividend = {0}", dividend);

                        ulong q_hat = dividend / firstDivisorByte;
                        ulong r_hat = dividend % firstDivisorByte;

                        //Console.WriteLine("q_hat = {0:X}, r_hat = {1:X}", q_hat, r_hat);

                        bool done = false;
                        while(!done)
                        {
                                done = true;

                                if(q_hat == 0x100000000 ||
                                   (q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos-2]))
                                {
                                        q_hat--;
                                        r_hat += firstDivisorByte;

                                        if(r_hat < 0x100000000)
                                                done = false;
                                }
                        }

                        for(int h = 0; h < divisorLen; h++)
                                dividendPart[h] = remainder[pos-h];

                        BigInteger kk = new BigInteger(dividendPart);
                        BigInteger ss = bi2 * (long)q_hat;

                        //Console.WriteLine("ss before = " + ss);
                        while(ss > kk)
                        {
                                q_hat--;
                                ss -= bi2;
                                //Console.WriteLine(ss);
                        }
                        BigInteger yy = kk - ss;

                        //Console.WriteLine("ss = " + ss);
                        //Console.WriteLine("kk = " + kk);
                        //Console.WriteLine("yy = " + yy);

                        for(int h = 0; h < divisorLen; h++)
                                remainder[pos-h] = yy.data[bi2.dataLength-h];

                        /*
                        Console.WriteLine("dividend = ");
                        for(int q = remainderLen - 1; q >= 0; q--)
                                Console.Write("{0:x2}", remainder[q]);
                        Console.WriteLine("\n************ q_hat = {0:X}\n", q_hat);
                        */

                        result[resultPos++] = (uint)q_hat;

                        pos--;
                        j--;
                }

                outQuotient.dataLength = resultPos;
                int y = 0;
                for(int x = outQuotient.dataLength - 1; x >= 0; x--, y++)
                        outQuotient.data[y] = result[x];
                for(; y < maxLength; y++)
                        outQuotient.data[y] = 0;

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

                if(outQuotient.dataLength == 0)
                        outQuotient.dataLength = 1;

                outRemainder.dataLength = shiftRight(remainder, shift);

                for(y = 0; y < outRemainder.dataLength; y++)
                        outRemainder.data[y] = remainder[y];
                for(; y < maxLength; y++)
                        outRemainder.data[y] = 0;
        }


        //***********************************************************************
        // Private function that supports the division of two numbers with
        // a divisor that has only 1 digit.
        //***********************************************************************

        private static void singleByteDivide(BigInteger bi1, BigInteger bi2,
                                             BigInteger outQuotient, BigInteger outRemainder)
        {
                uint[] result = new uint[maxLength];
                int resultPos = 0;

                // copy dividend to reminder
                for(int i = 0; i < maxLength; i++)
                        outRemainder.data[i] = bi1.data[i];
                outRemainder.dataLength = bi1.dataLength;

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

                ulong divisor = (ulong)bi2.data[0];
                int pos = outRemainder.dataLength - 1;
                ulong dividend = (ulong)outRemainder.data[pos];

                //Console.WriteLine("divisor = " + divisor + " dividend = " + dividend);
                //Console.WriteLine("divisor = " + bi2 + "\ndividend = " + bi1);

                if(dividend >= divisor)
                {
                        ulong quotient = dividend / divisor;
                        result[resultPos++] = (uint)quotient;

                        outRemainder.data[pos] = (uint)(dividend % divisor);
                }
                pos--;

                while(pos >= 0)
                {
                        //Console.WriteLine(pos);

                        dividend = ((ulong)outRemainder.data[pos+1] << 32) + (ulong)outRemainder.data[pos];
                        ulong quotient = dividend / divisor;
                        result[resultPos++] = (uint)quotient;

                        outRemainder.data[pos+1] = 0;
                        outRemainder.data[pos--] = (uint)(dividend % divisor);
                        //Console.WriteLine(">>>> " + bi1);
                }

                outQuotient.dataLength = resultPos;
                int j = 0;
                for(int i = outQuotient.dataLength - 1; i >= 0; i--, j++)
                        outQuotient.data[j] = result[i];
                for(; j < maxLength; j++)
                        outQuotient.data[j] = 0;

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

                if(outQuotient.dataLength == 0)
                        outQuotient.dataLength = 1;

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


        //***********************************************************************
        // Overloading of division operator
        //***********************************************************************

        public static BigInteger operator /(BigInteger bi1, BigInteger bi2)
        {
                BigInteger quotient = new BigInteger();
                BigInteger remainder = new BigInteger();

                int lastPos = maxLength-1;
                bool divisorNeg = false, dividendNeg = false;

                if((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative
                {
                        bi1 = -bi1;
                        dividendNeg = true;
                }
                if((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative
                {
                        bi2 = -bi2;
                        divisorNeg = true;
                }

                if(bi1 < bi2)
                {
                        return quotient;
                }

                else
                {
                        if(bi2.dataLength == 1)
                                singleByteDivide(bi1, bi2, quotient, remainder);
                        else
                                multiByteDivide(bi1, bi2, quotient, remainder);

                        if(dividendNeg != divisorNeg)
                                return -quotient;

                        return quotient;
                }
        }


        //***********************************************************************
        // Overloading of modulus operator
        //***********************************************************************

        public static BigInteger operator %(BigInteger bi1, BigInteger bi2)
        {
                BigInteger quotient = new BigInteger();
                BigInteger remainder = new BigInteger(bi1);

                int lastPos = maxLength-1;
                bool dividendNeg = false;

                if((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative
                {
                        bi1 = -bi1;
                        dividendNeg = true;
                }
                if((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative
                        bi2 = -bi2;

                if(bi1 < bi2)
                {
                        return remainder;
                }

                else
                {
                        if(bi2.dataLength == 1)
                                singleByteDivide(bi1, bi2, quotient, remainder);
                        else
                                multiByteDivide(bi1, bi2, quotient, remainder);

                        if(dividendNeg)
                                return -remainder;

                        return remainder;
                }
        }


        //***********************************************************************
        // Overloading of bitwise AND operator
        //***********************************************************************

        public static BigInteger operator &(BigInteger bi1, BigInteger bi2)
        {
                BigInteger result = new BigInteger();

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

⌨️ 快捷键说明

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