public static MyBigInt operator /(MyBigInt a, MyBigInt b) { var newInt = new MyBigInt(new List <int>()); var copyB = new MyBigInt(b) { isNegative = false }; if (a.isNegative != b.isNegative) { newInt.isNegative = true; } if (copyB == new MyBigInt("0")) { return(new MyBigInt("-1")); } var cur = new MyBigInt(new List <int>()); for (var i = a.numberElements.Count - 1; i >= 0; i--) { int x = NextBinSearch(a, copyB, cur, i); cur -= new MyBigInt(x) * copyB; newInt.numberElements.Insert(0, x); } DeleteZeros(newInt.numberElements); return(newInt); }
public static Tuple <MyBigInt, MyBigInt, MyBigInt> ExtendedEuclid(MyBigInt a, MyBigInt b) { MyBigInt x; MyBigInt y; MyBigInt q; MyBigInt r; if (b == new MyBigInt("0")) { return(Tuple.Create(a, new MyBigInt("1"), new MyBigInt("0"))); } var x2 = new MyBigInt("1"); var x1 = new MyBigInt("0"); var y2 = new MyBigInt("0"); var y1 = new MyBigInt("1"); while (!b.isNegative) { q = a / b; r = a - q * b; x = x2 - q * x1; y = y2 - q * y1; a = b; b = r; x2 = x1; x1 = x; y2 = y1; y1 = y; } return(Tuple.Create(a, x2, y2)); }
public static MyBigInt operator +(MyBigInt a, MyBigInt b) { if (!a.isNegative && b.isNegative) { MyBigInt copyB = new MyBigInt(b) { isNegative = false }; return(a - copyB); } else if (a.isNegative && !b.isNegative) { MyBigInt copyA = new MyBigInt(a) { isNegative = false }; return(b - copyA); } else if (a.isNegative && b.isNegative) { MyBigInt newInt = SumPositive(a, b); newInt.isNegative = true; return(newInt); } else { return(SumPositive(a, b)); } }
public static MyBigInt operator *(MyBigInt a, MyBigInt b) { MyBigInt newInt = new MyBigInt(new List <int>()); for (var i = 0; i < a.numberElements.Count + b.numberElements.Count; i++) { newInt.numberElements.Add(0); } for (var i = 0; i <= a.numberElements.Count - 1; i++) { long carry = 0; for (var j = 0; j < b.numberElements.Count || carry > 0; j++) { long s = (long)newInt.numberElements[i + j] + carry + (long)a.numberElements[i] * (long)(j < b.numberElements.Count ? b.numberElements[j] : 0); newInt.numberElements[i + j] = (int)(s % maxSizeElement); carry = s / maxSizeElement; } } DeleteZeros(newInt.numberElements); if (a.isNegative != b.isNegative) { newInt.isNegative = true; } return(newInt); }
private static MyBigInt SumPositive(MyBigInt a, MyBigInt b) { MyBigInt newInt = new MyBigInt(new List <int>()); var carry = 0; for (var i = 0; i <= Math.Max(a.numberElements.Count, b.numberElements.Count) - 1; i++) { if (i < a.numberElements.Count) { carry += a.numberElements[i]; } if (i < b.numberElements.Count) { carry += b.numberElements[i]; } newInt.numberElements.Add((carry % maxSizeElement)); carry /= maxSizeElement; } if (carry != 0) { newInt.numberElements.Add(carry); } DeleteZeros(newInt.numberElements); return(newInt); }
public void TestVeryLongPovitive() { var valueString = new MyBigInt("4388327487582347938491834832782738437"); var valueLong = new MyBigInt(2384427463283775745); Assert.AreEqual("4388327487582347938491834832782738437", valueString.ToString()); Assert.AreEqual("2384427463283775745", valueLong.ToString()); }
public static MyBigInt Inverse(MyBigInt a, MyBigInt n) { var e = ExtendedEuclid(a, n); if (e.Item1 == new MyBigInt("1")) { DeleteZeros(e.Item2.numberElements); return(e.Item2.isNegative ? e.Item2 + n : e.Item2); } return(new MyBigInt("0")); }
public void TestInverse() { var value1 = new MyBigInt("11"); var value2 = new MyBigInt(15); var value3 = new MyBigInt(3); var value4 = new MyBigInt(26); Assert.AreEqual("11", MyBigInt.Inverse(value1, value2).ToString()); Assert.AreEqual("3", MyBigInt.Inverse(value2, value1).ToString()); Assert.AreEqual("9", MyBigInt.Inverse(value3, value4).ToString()); Assert.AreEqual("2", MyBigInt.Inverse(value4, value3).ToString()); }
public void TestPow() { var valuePositive1 = new MyBigInt(4); var valuePositive2 = new MyBigInt(7); var valueNegative1 = new MyBigInt("-7"); Assert.AreEqual("112109763052329492462373924058515033811659000095239858763076604943862126505628591526845808763910755415889269318882151764705506265513744484970964975616", new MyBigInt("45478").Pow(new MyBigInt("32")).ToString()); Assert.AreEqual("16384", valuePositive1.Pow(valuePositive2).ToString()); Assert.AreEqual("2401", valuePositive2.Pow(valuePositive1).ToString()); Assert.AreEqual("-823543", valueNegative1.Pow(valuePositive2).ToString()); Assert.AreEqual("2401", valueNegative1.Pow(valuePositive1).ToString()); }
public static long ToLong(MyBigInt a) { long res = 0; long mul = 1; for (int i = 0; i < a.numberElements.Count; i++) { res += a.numberElements[i] * mul; mul *= maxSizeElement; } return(a.isNegative ? (-1) * res : res); }
private MyBigInt CalculateE(MyBigInt m) { MyBigInt e = m - 1; while (true) { if (e.IsPrimeNumber() && (e < m) && (MyBigInt.ExtendedEuclid(m, e).Item1 == new MyBigInt(1))) { return(e); } e--; } }
public void TestVeryLongNegative() { var value = new MyBigInt(-141253465); Assert.AreEqual("-141253465", value.ToString()); value = new MyBigInt(-1412534462467356465); Assert.AreEqual("-1412534462467356465", value.ToString()); value = new MyBigInt("-987654321123456789987654321123456789"); Assert.AreEqual("-987654321123456789987654321123456789", value.ToString()); value = new MyBigInt("-1"); Assert.AreEqual("-1", value.ToString()); }
public void TestComparison() { var valuePositive1 = new MyBigInt("5"); var valuePositive2 = new MyBigInt(10); var valueNegative1 = new MyBigInt("-10"); var valueNegative2 = new MyBigInt(-5); Assert.AreEqual(true, valuePositive1 < valuePositive2); Assert.AreEqual(false, valuePositive2 < valuePositive1); Assert.AreEqual(false, valueNegative1 > valueNegative2); Assert.AreEqual(true, valueNegative2 > valueNegative1); Assert.AreEqual(true, valuePositive1 > valueNegative2); Assert.AreEqual(false, valuePositive2 < valueNegative1); }
public void TestModule() { var valuePositive1 = new MyBigInt("12"); var valuePositive2 = new MyBigInt(5); var valueNegative1 = new MyBigInt("-12"); var valueNegative2 = new MyBigInt(-5); Assert.AreEqual("2", (valuePositive1 % valuePositive2).ToString()); Assert.AreEqual("2", (valuePositive1 % valueNegative2).ToString()); Assert.AreEqual("-2", (valueNegative1 % valuePositive2).ToString()); Assert.AreEqual("-2", (valueNegative1 % valueNegative2).ToString()); Assert.AreEqual("34", (new MyBigInt("167500108222301408246337399112597504") % 35).ToString()); Assert.AreEqual("21", (new MyBigInt("2576580875108218291929075869661") % 35).ToString()); }
public void Encrypt(MyBigInt p, MyBigInt q) { if (p.IsPrimeNumber() && q.IsPrimeNumber()) { var s = new StringBuilder(); try{ StreamReader sr = new StreamReader("in.txt"); while (!sr.EndOfStream) { s.Append(sr.ReadLine()); } sr.Close(); } catch { Console.WriteLine("Файл in.txt не найден"); return; } MyBigInt n = p * q; MyBigInt phi = (p - 1) * (q - 1); MyBigInt e = CalculateE(phi); MyBigInt d = (MyBigInt.Inverse(new MyBigInt(e), new MyBigInt(phi))); if (d == e) { d += phi; } List <string> result = Encode(s.ToString(), e, n); StreamWriter sw = new StreamWriter("out1.txt"); foreach (string item in result) { sw.WriteLine(item); } sw.Close(); PublicKey = new Tuple <MyBigInt, MyBigInt>(e, n); PrivateKey = new Tuple <MyBigInt, MyBigInt>(d, n); Console.WriteLine("Публичный ключ - ({0}, {1})", e, n); Console.WriteLine("Приватный ключ - ({0}, {1})", d, n); Process.Start("out1.txt"); } else { Console.WriteLine("p или q - не простые числа!"); } }
public void TestSubtraction() { var valuePositive1 = new MyBigInt("500"); var valuePositive2 = new MyBigInt(451); var valueNegative1 = new MyBigInt("-500"); var valueNegative2 = new MyBigInt(-451); Assert.AreEqual("49", (valuePositive1 - valuePositive2).ToString()); Assert.AreEqual("-49", (valuePositive2 - valuePositive1).ToString()); Assert.AreEqual("-49", (valueNegative1 - valueNegative2).ToString()); Assert.AreEqual("49", (valueNegative2 - valueNegative1).ToString()); Assert.AreEqual("951", (valuePositive1 - valueNegative2).ToString()); Assert.AreEqual("951", (valuePositive2 - valueNegative1).ToString()); Assert.AreEqual("-951", (valueNegative1 - valuePositive2).ToString()); Assert.AreEqual("-951", (valueNegative2 - valuePositive1).ToString()); }
public void TestMult() { var valuePositive1 = new MyBigInt("5"); var valuePositive2 = new MyBigInt(7); var valueNegative1 = new MyBigInt("-7"); var valueNegative2 = new MyBigInt(-5); Assert.AreEqual("35", (valuePositive1 * valuePositive2).ToString()); Assert.AreEqual("35", (valuePositive2 * valuePositive1).ToString()); Assert.AreEqual("35", (valueNegative1 * valueNegative2).ToString()); Assert.AreEqual("35", (valueNegative2 * valueNegative1).ToString()); Assert.AreEqual("-25", (valuePositive1 * valueNegative2).ToString()); Assert.AreEqual("-49", (valuePositive2 * valueNegative1).ToString()); Assert.AreEqual("-49", (valueNegative1 * valuePositive2).ToString()); Assert.AreEqual("-25", (valueNegative2 * valuePositive1).ToString()); }
public void TestDivision() { var valuePositive1 = new MyBigInt("5"); var valuePositive2 = new MyBigInt(10); var valueNegative1 = new MyBigInt("-10"); var valueNegative2 = new MyBigInt(-5); Assert.AreEqual("0", (valuePositive1 / valuePositive2).ToString()); Assert.AreEqual("2", (valuePositive2 / valuePositive1).ToString()); Assert.AreEqual("2", (valueNegative1 / valueNegative2).ToString()); Assert.AreEqual("0", (valueNegative2 / valueNegative1).ToString()); Assert.AreEqual("-1", (valuePositive1 / valueNegative2).ToString()); Assert.AreEqual("-1", (valuePositive2 / valueNegative1).ToString()); Assert.AreEqual("-1", (valueNegative1 / valuePositive2).ToString()); Assert.AreEqual("-1", (valueNegative2 / valuePositive1).ToString()); Assert.AreEqual("4785717377780040235609639974645642", (new MyBigInt("167500108222301408246337399112597504") / 35).ToString()); }
public void TestEquals() { var valuePositive1 = new MyBigInt("5"); var valuePositive2 = new MyBigInt(10); var valuePositive3 = new MyBigInt("10"); var valueNegative1 = new MyBigInt("-10"); var valueNegative2 = new MyBigInt(-5); var valueNegative3 = new MyBigInt("-5"); Assert.AreEqual(false, valuePositive1 == valuePositive2); Assert.AreEqual(false, valuePositive2 == valueNegative1); Assert.AreEqual(false, valueNegative1 == valueNegative2); Assert.AreEqual(false, valueNegative2 == valueNegative1); Assert.AreEqual(true, valuePositive2 == valuePositive2); Assert.AreEqual(true, valueNegative3 == valueNegative3); Assert.AreEqual(true, valuePositive2 == valuePositive3); Assert.AreEqual(true, valueNegative2 == valueNegative3); }
private static int NextBinSearch(MyBigInt a, MyBigInt copyB, MyBigInt cur, int i) { cur.isNegative = false; cur.numberElements.Insert(0, a.numberElements[i]); int x = 0, L = 0, R = maxSizeElement; while (L <= R) { int mid = (L + R) >> 1; if (copyB * new MyBigInt(mid) > cur) { x = mid; R = mid - 1; } else { L = mid + 1; } } return(x - 1); }
private string Decode(List <string> input, MyBigInt d, MyBigInt n) { var result = new StringBuilder(); foreach (string item in input) { long res; if (DecodedChars.ContainsKey(item)) { res = DecodedChars[item]; } else { res = MyBigInt.ToLong(new MyBigInt(item).Pow(d) % n); DecodedChars.Add(item, (int)res); } result.Append(characters[res]); } return(result.ToString()); }
private List <string> Encode(string s, MyBigInt e, MyBigInt n) { List <string> result = new List <string>(); for (int i = 0; i < s.Length; i++) { var index = (Array.IndexOf(characters, s[i]) == -1 ? 0 : Array.IndexOf(characters, s[i])); MyBigInt res; if (EncodedChars.ContainsKey(index)) { res = EncodedChars[index]; } else { res = new MyBigInt(index).Pow(e) % n; EncodedChars.Add(index, res); } result.Add(res.ToString()); } return(result); }
private static MyBigInt MinusPositive(MyBigInt a, MyBigInt b) { var newInt = new MyBigInt(new List <int>()); var carry = 0; for (var i = 0; i <= a.numberElements.Count - 1; i++) { carry += a.numberElements[i] - (i < b.numberElements.Count ? b.numberElements[i] : 0); if (carry < 0) { newInt.numberElements.Add((carry + maxSizeElement)); carry = -1; } else { newInt.numberElements.Add(carry); carry = 0; } } DeleteZeros(newInt.numberElements); return(newInt); }
public MyBigInt Pow(MyBigInt power) { var pow = new MyBigInt(power); if (this == new MyBigInt("0") || this == new MyBigInt("1")) { return(this); } MyBigInt r = new MyBigInt("1"); var thisNumber = this; while (pow > new MyBigInt("0")) { if (pow % 2 == new MyBigInt("1")) { r *= thisNumber; } thisNumber *= thisNumber; pow /= new MyBigInt("2"); } DeleteZeros(r.numberElements); return(r); }
public static MyBigInt operator %(MyBigInt a, MyBigInt b) { var copyB = new MyBigInt(b) { isNegative = false }; if (copyB == new MyBigInt("0")) { return(new MyBigInt("-1")); } MyBigInt ans = new MyBigInt(new List <int>()); for (var i = a.numberElements.Count - 1; i >= 0; i--) { int x = NextBinSearch(a, copyB, ans, i); ans -= new MyBigInt(x) * copyB; } DeleteZeros(ans.numberElements); ans.isNegative = a.isNegative; return(ans); }
public void Decipher(MyBigInt d, MyBigInt n) { List <string> input = new List <string>(); try { StreamReader sr = new StreamReader("out1.txt"); while (!sr.EndOfStream) { input.Add(sr.ReadLine()); } sr.Close(); } catch { Console.WriteLine("Файл out1.txt не найден"); return; } string result = Decode(input, d, n); StreamWriter sw = new StreamWriter("out2.txt"); sw.WriteLine(result); sw.Close(); Process.Start("out2.txt"); }
public MyBigInt(MyBigInt i) { numberElements = i.numberElements; isNegative = i.isNegative; }