Өте үлкен сандармен арифметикалық амалдарды орындау (Класс реализациясы - бета)

Бағдарламалау
RSA алгоритмнің реализациясы үшін бізге өте үлкен сандармен жұмыс істейтін класс қажет болған болатын. Класстың коды көп болған соң, бөлек жазбаға шығаруды жөн көрдім. Сонымен, төменде «сівежий» код, қабыл алыңыздар))

Ескертіп қояйын, бұл бета нұсқа, бірге жетілдірейік!

 /// <summary>
        /// Екі санның қосындысын анықтайды
        /// </summary>
        /// <param name="a">Бірінші қосылғыш</param>
        /// <param name="b">Екінші қосылғыш</param>
        /// <returns></returns>
        public static string Plus(string a, string b)
        {
            bool aIsPositive = IsPositive(a);
            bool bIsPositive = IsPositive(b);
            if ((aIsPositive && bIsPositive) || (!aIsPositive && !bIsPositive))
            {
                string character = string.Empty;
                if (!aIsPositive)
                {
                    a = Modul(a);
                    b = Modul(b);
                    character = "-";
                }
                int r = 0;
                int k = a.Length >= b.Length ? a.Length : b.Length;
                k++;
                a = PrepareNumber(a, k);
                b = PrepareNumber(b, k);
                string res = string.Empty;
                for (int i = 0; i < k; i++)
                {
                    int c1 = Convert.ToInt32(a[k - 1 - i].ToString());
                    int c2 = Convert.ToInt32(b[k - 1 - i].ToString());
                    int c3 = c1 + c2 + r;
                    r = c3 / 10;
                    res = (c3 - 10 * r).ToString() + res;
                };
                return character + CorrectNumber(res);
            }
            else if (aIsPositive && !bIsPositive)
            {
                return Minus(a, Modul(b));
            }
            else if (!aIsPositive && bIsPositive)
            {
                return Minus(b, Modul(a));
            }
            return "NaN";
        }

        /// <summary>
        /// Екі санның айырмайсын анықтайды
        /// </summary>
        /// <param name="a">Алынғыш</param>
        /// <param name="b">Алғыш</param>
        /// <returns></returns>
        public static string Minus(string a, string b)
        {
            bool aIsPositive = IsPositive(a);
            bool bIsPositive = IsPositive(b);
            if (aIsPositive && bIsPositive)
            {
                string character = !IsBigger(a, b) ? "-" : "";
                int k = a.Length >= b.Length ? a.Length : b.Length;
                if (!IsBigger(a, b))
                {
                    string s = b;
                    b = a;
                    a = s;
                }
                k++;
                a = PrepareNumber(a, k);
                b = PrepareNumber(b, k);


                bool r = false;
                string res = string.Empty;
                for (int i = 0; i < k; i++)
                {
                    int c1 = Convert.ToInt32(a[k - 1 - i].ToString()) - Convert.ToInt32®;
                    int c2 = Convert.ToInt32(b[k - 1 - i].ToString());
                    r = c1 < c2;
                    int c3 = 10 * Convert.ToInt32® + c1 - c2;
                    res = c3 + res;
                };
                return character + CorrectNumber(res);
            }
            else if (aIsPositive && !bIsPositive)
            {
                return Plus(a, Modul(b));
            }
            else if (!aIsPositive && bIsPositive)
            {
                return ChangeCharacter(Plus(Modul(a), Modul(b)));
            }
            else if (!aIsPositive && !bIsPositive)
            {
                return Minus(Modul(b), Modul(a));
            }
            return "NaN";
        }

        /// <summary>
        /// Санды жұмыс жасауға дайындайды
        /// </summary>
        /// <param name="s">Сан</param>
        /// <param name="k">Қажетті ұзындық</param>
        /// <returns></returns>
        private static string PrepareNumber(string s, int k)
        {
            string zeros = string.Empty;
            for (int i = 0; i < k - s.Length; i++)
            {
                zeros += "0";
            }
            return zeros + s;
        }
        
        /// <summary>
        ///Санды түзейді 
        /// </summary>
        /// <param name="number">Сан</param>
        /// <returns></returns>
        private static string CorrectNumber(string number)
        {
            int k = 0;
            while (number[k] == '0' && k < number.Length - 1)
            {
                k++;
            }
            string res = string.Empty;
            for (int i = k; i < number.Length; i++)
            {
                res += number[i];
            }
            return res != "" ? res : "0";
        }

        /// <summary>
        /// Санның модулін анықтайды
        /// </summary>
        /// <param name="number">Берілген сан</param>
        /// <returns></returns>
        public static string Modul(string number)
        {
            if (number[0] == '-')
            {
                string res = string.Empty;
                for (int i = 1; i < number.Length; i++)
                {
                    res += number[i];
                }
                return res;
            }
            return number;
        }

        /// <summary>
        /// Санның оң екендігін анықтайды
        /// </summary>
        /// <param name="number">Сан</param>
        /// <returns></returns>
        private static bool IsPositive(string number)
        {
            return number[0] != '-';
        }

        /// <summary>
        /// Санның таңбасын қарсыға айыстырады
        /// </summary>
        /// <param name="number">Сан</param>
        /// <returns></returns>
        private static string ChangeCharacter(string number)
        {
            if (number[0] == '-')
            {
                return Modul(number);
            }
            else
            {
                return "-" + number;
            }
        }

        /// <summary>
        ///Жұптың алғашқысы кейінігісінен үлкен екендігін анықтайды
        /// </summary>
        /// <param name="a">Бірінші сан</param>
        /// <param name="b">Екінші сан</param>
        /// <returns></returns>
        public static bool IsBigger(string a, string b)
        {
            bool aIsPositive = IsPositive(a);
            bool bIsPositive = IsPositive(b);
            if (aIsPositive && bIsPositive)
            {
                if (a.Length == b.Length)
                {
                    for (int i = 0; i < a.Length; i++)
                    {
                        if (a[i] != b[i])
                        {
                            return Convert.ToInt32(a[i].ToString()) > Convert.ToInt32(b[i].ToString());
                        }
                    }
                }
                else
                {
                    return a.Length > b.Length;
                }
            }
            else if (aIsPositive && !bIsPositive)
            {
                return true;
            }
            else if (!aIsPositive && bIsPositive)
            {
                return false;
            }
            else
            {
                a = Modul(a);
                b = Modul(b);
                return IsBigger(b, a);
            }
            return true;
        }
        /// <summary>
        /// Екі санды көбейтеді
        /// </summary>
        /// <param name="a">Бірінші көбейткіш</param>
        /// <param name="b">Екінші көбейткіш</param>
        /// <returns></returns>
        public static string MultiPly(string a, string b)
        {
            bool aIsPositive = IsPositive(a);
            bool bIsPositive = IsPositive(b);
            if (aIsPositive && bIsPositive)
            {
                string i = "0";
                string res = "0";
                while (i != a)
                {
                    res = Plus(res, b);
                    i = Plus(i, "1");
                }
                return res;
            }
            else if (aIsPositive && !bIsPositive)
            {
                return ChangeCharacter(MultiPly(a, Modul(b)));
            }
            else if (!aIsPositive && bIsPositive)
            {
                return ChangeCharacter(MultiPly(Modul(a), b));
            }
            else if (!aIsPositive && !bIsPositive)
            {
                return MultiPly(Modul(a), Modul(b));
            }
            return "NaN";
        }

        /// <summary>
        /// Бөлу, бүтін бөлшегін қайтарады
        /// </summary>
        /// <param name="a">Бөлінгіш</param>
        /// <param name="b">Бөлгіш</param>
        /// <returns></returns>
        public static string Div(string a, string b)
        {
            if (b == "0") { return "NaN"; };
            if (!IsBigger(Modul(a), Modul(b))) { return "0"; }
            bool aIsPositive = IsPositive(a);
            bool bIsPositive = IsPositive(b);
            if (aIsPositive && bIsPositive)
            {

                string res = "0";
                while (IsBigger(a, b))
                {
                    a = Minus(a, b);
                    res = Plus(res, "1");
                }
                return res;
            }
            else if (aIsPositive && !bIsPositive)
            {
                return ChangeCharacter(Div(a, Modul(b)));
            }
            else if (!aIsPositive && bIsPositive)
            {
                return ChangeCharacter(Div(Modul(a), b));
            }
            else if (!aIsPositive && !bIsPositive)
            {
                return Div(Modul(a), Modul(b));
            }
            return "NaN";
        }
        /// <summary>
        /// Қалдық табу
        /// </summary>
        /// <param name="a">Бөлінгіш</param>
        /// <param name="b">Бөлгіш</param>
        /// <returns></returns>
        public static string Mod(string a, string b)
        {
            if (b == "0") { return "NaN"; };
            if (!IsBigger(Modul(a), Modul(b))) { return a; }
            bool aIsPositive = IsPositive(a);
            bool bIsPositive = IsPositive(b);
            if (aIsPositive && bIsPositive)
            {
                while (IsBigger(a, b))
                {
                    a = Minus(a, b);
                }
                return a;
            }
            else if (aIsPositive && !bIsPositive)
            {
                return ChangeCharacter(Mod(a, Modul(b)));
            }
            else if (!aIsPositive && bIsPositive)
            {
                return ChangeCharacter(Mod(Modul(a), b));
            }
            else if (!aIsPositive && !bIsPositive)
            {
                return ChangeCharacter(Mod(Modul(a), Modul(b)));
            }
            return "NaN";

        }
        /// <summary>
        /// Санның дәрежесін анықтау
        /// </summary>
        /// <param name="a">Сан</param>
        /// <param name="n">Дәреже</param>
        /// <returns></returns>
        public static string Pow(string a, string n)
        {
            string i = "1";
            while (i != n)
            {
                a = MultiPly(a, a);
                i = Plus(i, "1");
            }
            return a;
        }

14 пікір

avatar
Keremet, birak komment jane tysindirmelermen jazsanyz odan jaksy bolady, biz tysinemiz, 1-2 aidan kein oziniz tyse alasyz.))
avatar
Ия, кеше коммент жазуға үлгермей ұйықтап кетіппін. ИнщаАлла сәл кешірек қосып қоямын
avatar
не деген код… шатысып кеттім ғой...))
avatar
Ондай бір қиындығы жоқ. Қосуды түсінсең, ар жағы оңай
avatar
мұндай кодтарды қарайтын деңгейге жетпеген сияқтымын…
avatar
Білмеймін, бұл жерде қарапайым операторлар, қосуды қағаздағы қалай қосамыз, дәл сола жасадым. Кейінірек, комменттармен жазғанда түсініктірек болады деп ойлаймын
avatar
иәә… солай істесеңіз нұр үстіне нұр болар еді))
avatar
Керемет, тема :))
avatar
Көбейту амалын қосу арқылы жасаған едім, тезірек жұмыс істеуі үшін қолмен көбейтуге ұқсату керек сияқты.
avatar
негізі C# та соған арналған BigInteger дейтін дайын тип бар
avatar
Ол 1024 биттік сандармен жұмыс жасай алады ма?
avatar
білуімше жасай алады
avatar
Негізі, дайын кітапханалардың бар болу керектігін білгем. Бірақ, оны іздемедім, RSA толық өзім жазып шыққым келді
avatar
Ох, дәрежеге шығарғанда қате бар екен))
Тек қана тіркелген және авторизациядан өткен қолданушылар пікір қалдыра алады.