static public bigInt operator %(bigInt x, bigInt n) { if (n.equalToZero()) { throw new ArithmeticException("Cannot module by zero!"); } else { x = standardize(x); n = standardize(n); bigInt one = new bigInt("1"); bigInt zero = new bigInt("0"); if (x == n) { return(zero); } else { bigInt a, b, c; bigInt i = one; while (x > n || x == n) { if (n._length > x._length / 2) { x = x - n; } else { int q = n._length; String temp = ""; for (int j = 0; j < n._length; j++) { temp += ('1' - n._bits[j]); } c = new bigInt(temp); c = c + one; b = x >> q; a = new bigInt(x._bits.Substring(x._length - q)); bigInt bvalue = b; while (i < c) { b = b + bvalue; i = i + one; } if (b.equalToZero()) { x = x - n; } else { x = a + b; } i = one; } } } return(x); } }
static bigInt GCD(bigInt a, bigInt b) { if (a.equalToZero() || b.equalToZero()) { return(a + b); } string bits = "1"; bigInt gcd = new bigInt(bits); while (a._bits[a._length - 1] == '0' && b._bits[b._length - 1] == '0') { a = a >> 1; b = b >> 1; gcd = gcd << 1; } while (!a.equalToZero()) { while (a._bits[a._length - 1] == '0') { a = a >> 1; } while (b._bits[b._length - 1] == '0') { b = b >> 1; } bigInt t; if (a > b) { t = a - b; } else { t = b - a; } t = t >> 1; if (a > b || a == b) { a = t; } else { b = t; } } if (a._length > b._length) { gcd = gcd >> b._length; } else { gcd = gcd >> a._length; } gcd = bigInt.standardize(gcd); return(gcd); }
// operator minus two big integer static public bigInt operator -(bigInt a, bigInt b) { a = standardize(a); b = standardize(b); if (a == b) { return(new bigInt()); } else if (a < b) { throw new ArithmeticException("First parameter must equal or bigger than second parameter"); } else { int mem = 0, flag = 1; String aRev, bRev; if (a._bits.Length >= b._bits.Length) { flag = 0; } if (flag == 0) { aRev = Program.reverseString(a._bits); bRev = Program.reverseString(b._bits); } else { bRev = Program.reverseString(a._bits); aRev = Program.reverseString(b._bits); } String sum = ""; // Make bRev have the same length as aRev bRev = bRev.PadRight(aRev.Length, '0'); // OR every bits of aRev, bRev and mem for (int i = 0; i < aRev.Length; i++) { int temp = (aRev[i] - 48) - (bRev[i] - 48) + mem; if (temp < 0) { temp += 2; mem = -1; } else { mem = 0; } sum += (temp % 2).ToString(); } bigInt s = new bigInt(Program.reverseString(sum)); return(s); } }
static int countTrueBits(bigInt n) { int count = 0; for (int i = 0; i < n._length; i++) { if (n._bits[i] == '1') { count++; } } return(count); }
static bigInt subMod(bigInt a, bigInt b, bigInt n) { a = a % n; b = b % n; // a, b thuoc Zn if (a < b) { return(a - b + n); } else { return(a - n); } }
static bigInt addMod(bigInt a, bigInt b, bigInt n) { a = a % n; b = b % n; // a, b thuoc Zn if (a + b < n) { return(a + b); } else { return(a + b - n); } }
// Return the Decimal value of the bigInt (use for bigInt <= 32 bits) static int value(bigInt num) { if (num._length > 32) { throw new ArithmeticException("The number size is bigger than 32 bits!"); } int v = 0; String temp = Program.reverseString(num._bits); for (int i = 0; i < temp.Length; i++) { v += ((temp[i] - 48) * (int)Math.Pow(2, i)); } return(v); }
static public bigInt operator >>(bigInt a, int n) { bigInt result; String bits = ""; if (n < a._length) { bits = a._bits.Substring(0, a._length - n); bits = bits.PadLeft(a._length, '0'); result = new bigInt(bits); } else { result = new bigInt(bits.Length); } return(result); }
static public bigInt operator <<(bigInt a, int n) { String bits = ""; if (a._bits.IndexOf('1') < n) { bits = a._bits.Substring(a._bits.IndexOf('1')); bits = bits.PadRight(bits.Length + n - a._bits.IndexOf('1'), '0'); } else { bits = a._bits.Substring(n); bits = bits.PadRight(bits.Length + n, '0'); } bigInt result = new bigInt(bits); return(result); }
// Behaviors // operator plus two big integer static public bigInt operator +(bigInt a, bigInt b) { a = standardize(a); b = standardize(b); int mem = 0, flag = 1; String aRev, bRev; if (a._bits.Length >= b._bits.Length) { flag = 0; } if (flag == 0) { aRev = Program.reverseString(a._bits); bRev = Program.reverseString(b._bits); } else { bRev = Program.reverseString(a._bits); aRev = Program.reverseString(b._bits); } String sum = ""; // Make bRev have the same length as aRev bRev = bRev.PadRight(aRev.Length, '0'); // OR every bits of aRev, bRev and mem for (int i = 0; i < aRev.Length; i++) { sum += ((aRev[i] - 48 + bRev[i] - 48 + mem) % 2).ToString(); if (aRev[i] - 48 + bRev[i] - 48 + mem < 2) { mem = 0; } else { mem = 1; } } sum += mem.ToString(); bigInt s = new bigInt(Program.reverseString(sum)); return(s); }
static bigInt mulMod(bigInt a, bigInt b, bigInt n) { bigInt result = new bigInt("0"); a = a % n; b = b % n; // a, b thuoc Zn if (b._bits[b._length - 1] == '1') { result = a; } for (int i = 1; i < b._length; i++) { a = addMod(a, a, n); if (b._bits[b._length - 1 - i] == '1') { result = addMod(result, a, n); } } return(result); }
static public bigInt standardize(bigInt a) { bigInt zero = new bigInt("0"); if (a._bits.IndexOf('1') != 0) { if (a._bits.IndexOf('1') != -1) { String bits = a._bits.Substring(a._bits.IndexOf('1')); bigInt result = new bigInt(bits); return(result); } else { return(zero); } } else { return(a); } }
static bigInt powerMod(bigInt x, bigInt p, bigInt n) { //Return: result = (x ^ p) % n x = x % n; String bits = "1"; bigInt result = new bigInt(bits); // if (p == 0) return 1; if (p.equalToZero()) { return(result); } else { //Cach 1: //bigInt a = new bigInt(x._bits); //if (p._bits[p._length - 1] == '1') result = x; //for (int i = 1; i < p._length; i++) //{ // a = mulMod(a, a, n); // if (p._bits[p._length - 1 - i] == '1') result = mulMod(result, a, n); //} //Cach 2 for (int i = 0; i < p._length; i++) { result = mulMod(result, result, n); if (p._bits[i] == '1') { result = mulMod(result, x, n); } } } result = bigInt.standardize(result); return(result); }
static void Main(string[] args) { Console.WriteLine("Du lieu lan luot cho x, y, p, n phai thoa dieu kien gia tri x, y < n va p tuy y!"); Console.WriteLine("Neu khong thoa dieu kien tren qua trinh tinh toan se xay ra kha lau khi gap so lon!"); Console.WriteLine("Lua chon cac cach tao du lieu:"); Console.WriteLine("1. Lay du lieu tu file data.txt (moi dong tuong ung voi chuoi bit cua lan luot cac so: x, y, p, n)."); Console.WriteLine("2. Tao du lieu ngau nhien cho tung so."); Console.Write("Nhap lua chon (1 hoac 2): "); int select = -1; select = Console.ReadKey().KeyChar; while (select != '1' && select != '2') { Console.Write("\nLua chon khong hop le! Vui long nhap lai: "); select = Console.ReadKey().KeyChar; } String str1 = ""; String str2 = ""; String str3 = ""; String str4 = ""; Console.WriteLine(); if (select == '1') { //đọc dữ liệu từ file data.txt, các số x, y, p, n lần lượt là các dòng trong file data.txt string filePath = @"data.txt"; string[] lines = ReadAllLines(filePath); if (lines == null) { Console.ReadKey(); return; } int lineNum = 0; str1 = lines[lineNum]; str2 = lines[lineNum + 1]; str3 = lines[lineNum + 2]; str4 = lines[lineNum + 3]; } if (select == '2') { // bigIntGen(int n) là hàm tạo ra số nguyên ngẫu nhiên n bit Console.WriteLine("Nhap do dai chuoi nhi phan cua tung so: "); Console.Write("x.Length = "); int len = ReadInt(); if (len != -1) { str1 = new String(bigIntGen(len)); } Console.Write("y.Length = "); len = ReadInt(); if (len != -1) { str2 = new String(bigIntGen(len)); } Console.Write("p.Length = "); len = ReadInt(); if (len != -1) { str3 = new String(bigIntGen(len)); } Console.Write("n.Length = "); len = ReadInt(); if (len != -1) { str4 = new String(bigIntGen(len)); } } bigInt x = new bigInt(str1); bigInt y = new bigInt(str2); bigInt p = new bigInt(str3); bigInt n = new bigInt(str4); Console.WriteLine($"x = {x._bits}"); // x thuoc Zn Console.WriteLine($"y = {y._bits}"); // y thuoc Zn Console.WriteLine($"p = {p._bits}"); Console.WriteLine($"n = {n._bits}"); Console.WriteLine($"gcd (x, y) = {GCD(x, y)._bits}"); Console.WriteLine($"x * y (mod n) = {mulMod(x, y, n)._bits}"); Console.WriteLine($"x ^ p (mod n) = {powerMod(x, p, n)._bits}"); Console.WriteLine("Done!"); Console.ReadKey(true); }