刚刚注册,因为我对这个愚蠢的错误感到震惊。
我用 1 个源文件中的所有内容以一种快速而肮脏的方式计算椭圆曲线。然后我想清理我的代码并开始将不同文件中的函数和类分开。我用 C++ 编程已经很长时间了,所以我想这是一个非常愚蠢的初学者错误。
所以我得到了 LNK1169-Error 和 LNK2005-Error 并且我找到的解决方案是关于包括 .cpp 我没有做。我虽然发现了 extern-keyword,但这似乎是全局变量的一种解决方案。
也许有人可以帮助我。
编辑:很抱歉放了这么多代码。我只是不知道什么与错误相关,什么不相关。
我得到的错误是这样的:
fatal error LNK1169: one or more multiply defined symbols found. Elliptic 1 C:\Users\Björn\documents\visual studio 2015\Projects\Elliptic 1\Debug\Elliptic 1.exe
error LNK2005 "public: int __thiscall Value::operator==(class Value const &)" (??8Value@@QAEHABV0@@Z) already defined in Tests.obj
error LNK2005 "public: int __thiscall Value::operator==(int)" (??8Value@@QAEHH@Z) already defined in Tests.obj
这是我的代码:
值.hpp
#pragma once
extern int PRIME;
// An own Int-Class to overload operators with modulo
class Value
{
public:
int v;
static friend std::ostream& operator<<(std::ostream& os, const Value& a);
Value()
{
this->v = 0;
}
Value(int a)
{
this->v = a;
}
Value operator+(const Value& other)
{
return Value((this->v + other.v) % PRIME);
}
Value operator+(int a)
{
return Value((this->v + a) % PRIME);
}
Value operator-(const Value& other)
{
Value t = Value((v - other.v) % PRIME);
if (t.v < 0)
{
t = t + PRIME;
return t;
}
return t;
}
Value operator-(int a)
{
Value t = Value((v - a) % PRIME);
if (t.v < 0)
{
t = t + PRIME;
return t;
}
return t;
}
void operator=(const Value other)
{
this->v = other.v;
}
Value operator*(const Value& a);
Value operator*(int a);
Value operator^(int a);
Value operator/(const Value& a);
int operator!=(int b);
int operator!=(const Value& b);
int operator==(int b);
int operator==(const Value& b);
Value operator~();
};
Value Value::operator*(const Value& a)
{
return Value((this->v*a.v) % PRIME);
}
Value Value::operator*(int a)
{
return Value((this->v*a) % PRIME);
}
Value Value::operator^(int b)
{
Value ret(1);
Value mul(this->v);
while (b)
{
if (b & 1)
ret = (ret * mul);
b = (b >> 1);
mul = mul * mul;
}
return ret;
}
Value Value::operator/(const Value& a)
{
if (a.v == 0)
return Value(0);
Value f = (Value)a ^ (PRIME - 2);
return *this * f;
}
int Value::operator!=(int b)
{
if (this->v != b)
return 1;
return 0;
}
int Value::operator!=(const Value& b)
{
if (this->v != b.v)
return 1;
return 0;
}
int Value::operator==(int b)
{
if (this->v == b)
return 1;
return 0;
}
int Value::operator==(const Value& b)
{
if (this->v == b.v)
return 1;
return 0;
}
Value Value::operator~()
{
return *this ^ ((PRIME - 1 + 2) / 4);
}
std::ostream& operator<<(std::ostream& os, const Value& a)
{
return os << a.v;
}
点.hpp
#pragma once
#include "Value.hpp"
#include <iostream>
class Point
{
public:
Value x;
Value y;
Value z = 0;
static friend std::ostream& operator<<(std::ostream& os, const Point& p);
Point(int a, int b)
{
x.v = a;
y.v = b;
}
Point(int a, int b, int c)
{
x.v = a;
y.v = b;
z.v = c;
}
Point(Value a, Value b)
{
x.v = a.v;
y.v = b.v;
}
Point(Value a, Value b, Value c)
{
x.v = a.v;
y.v = b.v;
z.v = c.v;
}
Point& operator=(const Point& other)
{
x.v = other.x.v;
y.v = other.y.v;
z.v = other.z.v;
return *this;
}
int operator==(Point& other)
{
if (this->x == other.x && this->y == other.y && this->z == other.z)
return 1;
return 0;
}
int operator!=(Point& other)
{
if (this->x != other.x || this->y != other.y || this->z != other.z)
return 1;
return 0;
}
};
std::ostream& operator<<(std::ostream& os, const Point& p)
{
if ((Value)p.z == 0)
return os << "(" << p.x.v << "," << p.y.v << ")";
else
return os << "(" << p.x.v << "," << p.y.v << "," << p.z.v << ")";
}
助手.hpp
#pragma once
#include "Point.hpp"
#include <vector>
// Forward declaration
int isEC(Value a, Value b);
Value calcEC(int x, Value a, Value b);
int testSqr(Value ySqr);
// Point Addition
Point add(Point p1, Point p2, Value a)
{
// 2D Addition
if (p1.z == 0 && p2.z == 0)
{
// 2 different points
if (p1.x.v != p2.x.v || p1.y.v != p2.y.v)
{
// m = (y2-y1)/(x2-x1)
Value h = p2.y - p1.y;
Value j = p2.x - p1.x;
Value m = h / j;
// x3 = m^2-x1-x2
Value f = m*m;
Value g = f - p1.x;
Value x3 = g - p2.x;
// y3 = m(x1-x3)-y1
Value t = p1.x - x3;
Value l = m * t;
Value y3 = l - p1.y;
if (x3.v < 0)
x3 = x3 + PRIME;
if (y3.v < 0)
y3 = y3 + PRIME;
return Point(x3, y3);
}
// Same points
else
{
// m = (3*x1^2+a)/(2*y1)
Value f = p1.x ^ 2;
Value g = f * 3;
Value h = g + a;
Value j = p1.y * 2;
Value m = h / j;
// x3 = m^2-2*x1
Value t = m*m;
Value x = p1.x * 2;
Value x3 = t - x;
// y3 = m(x1-x3)-y1
Value z = p1.x - x3;
Value i = m * z;
Value y3 = i - p1.y;
if (x3.v < 0)
x3 = x3 + PRIME;
if (y3.v < 0)
y3 = y3 + PRIME;
return Point(x3, y3);
}
}
// 3D Addition - Same points
else if (p1 == p2 && p1.z == 1 && p2.z == 1)
{
Value A = p1.y ^ 2;
Value B = p1.x * A * 4;
Value C = (A ^ 2) * 8;
Value D = (p1.x ^ 2)* 3 + a*(p1.z ^ 4);
//Value x3 = (((3 * (p1.x ^ 2) + a*(p1.z ^ 4)) ^ 2) - 8 * p1.x*(p1.y ^ 2));
Value x3 = (D ^ 2) - B * 2;
//Value y3 = (3 * (p1.x ^ 2) + a*(p1.z ^ 4)*(4 * p1.x*(p1.y ^ 2) - x3) - 8 * (p1.y ^ 4));
Value y3 = D*(B - x3) - C;
Value z3 = p1.y*p1.z * 2;
return Point(x3, y3, z3);
}
// 3D Addition - 2 different points
else if (p1 != p2)
{
Value A = p1.z ^ 2;
Value B = p1.z * A;
Value C = p2.x * A;
Value D = p2.y * B;
Value E = C - p1.x;
Value F = D - p1.y;
Value G = E ^ 2;
Value H = G * E;
Value I = p1.x * G;
Value x3 = (F ^ 2) - (H + (I * 2));
Value y3 = F*(I - x3) - p1.y*H;
Value z3 = p1.z * E;
return Point(x3, y3, z3);
}
return Point(0, 0, 0);
}
// Find all points and print them
std::vector<Point> findAllPoints(Value a, Value b)
{
Value ySqr;
std::vector<Point> vec;
std::cout << "Alle Punkte fuer a = " << a << ", b = " << b << " und Prime = " << PRIME << std::endl;
// Is it an elliptic curve?
if (isEC(a, b))
{
// Test all x-Values
for (int x = 0; x <= PRIME - 1;x++)
{
// y^2
ySqr = calcEC(x, a, b);
// Test ySqr for square by root
if (testSqr(ySqr))
{
//sqrt operator ~
Value yPos = ~ySqr;
std::cout << "(" << x << "," << yPos << ")\t";
Value yNeg = yPos - (yPos * 2);
// Save found points into vector
vec.push_back(Point(x, yPos));
vec.push_back(Point(x, yNeg));
if (yNeg != 0)
std::cout << "(" << x << "," << yNeg << ")\t";
}
}
//vec.insert(vec.begin(), Point(INFINITY, INFINITY));
std::cout << std::endl;
}
else
// Not an ellpitic curve
std::cout << "\na and b are not leading to an ellptic curve.";
return vec;
}
// Test if a and b lead to an EC
int isEC(Value a, Value b)
{
if ((a ^ 3) * 4 + (b ^ 2) * 27 != 0)
return 1;
return 0;
}
// Calculate y^2
Value calcEC(int x, Value a, Value b)
{
return Value(a*x + (x ^ 3) + b);
}
// Test ySqr for square by root
int testSqr(Value ySqr)
{
if ((ySqr ^ ((PRIME - 1) / 2)) == 1 || ySqr == 0)
return 1;
return 0;
}
测试.hpp
#pragma once
#include "Helper.hpp"
class Tests
{
public:
void twoDAdd(Value a, Value b);
void twoDDoubling(Value a, Value b);
void threeDAdd(Value a, Value b);
void threeDDoubling(Value a, Value b);
};
测试.cpp
#pragma once
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <time.h>
#include "Tests.hpp"
// 2D - Addition
void Tests::twoDAdd(Value a, Value b)
{
std::cout << "\n========== 2D Addition ==========\n";
Point p2D1 = Point(5, 22);
Point p2D2 = Point(16, 27);
std::cout << p2D1 << " + " << p2D2 << " = " << add(p2D1, p2D2, a);
std::cout << std::endl;
}
// 2D - Doubling
void Tests::twoDDoubling(Value a, Value b)
{
std::cout << "\n========== 2D Doubling ==========\n";
Point p2D1 = Point(5, 22);
std::cout << "2 * " << p2D1 << " = " << add(p2D1, p2D1, a);
std::cout << std::endl << std::endl;
}
// 3D - Addition
void Tests::threeDAdd(Value a, Value b)
{
std::cout << "\n========== 3D Addition ==========\n";
std::cout << "All points for a = " << a << ", b = " << b << " and prime = " << PRIME << std::endl;
std::vector<Point> allPoints = findAllPoints(a, b);
std::srand(time(NULL));
int random = std::rand() % (allPoints.capacity() - 1);
Point tmp = allPoints.at(random);
std::cout << std::endl << "Random Point 1: " << tmp << std::endl << std::endl;
tmp.z = 1;
Point p1 = add(tmp, tmp, a);
std::cout << p1 << std::endl;
random = std::rand() % (allPoints.capacity() - 1);
tmp = allPoints.at(random);
std::cout << std::endl << "Random Point 2: " << tmp << std::endl << std::endl;
tmp.z = 1;
Point p2 = add(tmp, tmp, a);
std::cout << p2 << std::endl;
Point p3 = add(p1, p2, a);
std::cout << p3 << std::endl;
}
// 3D - Doubling
void Tests::threeDDoubling(Value a, Value b)
{
std::cout << "\n========== 3D Doubling ==========\n";
std::cout << "All points for a = " << a << ", b = " << b << " and prime = " << PRIME << std::endl;
std::vector<Point> allPoints = findAllPoints(a, b);
int random = std::rand() % (allPoints.capacity() - 1);
Point tmp = allPoints[random];
std::cout << std::endl << "Random Point: " << tmp << std::endl << std::endl;
Point p1 = add(tmp, tmp, a);
std::cout << p1 << std::endl;
tmp.z = 1;
Point p2 = add(tmp, tmp, a);
std::cout << p2 << std::endl;
Point p3 = Point(p2.x / (p2.z ^ 2), p2.y / (p2.z ^ 3));
std::cout << p3 << std::endl;
if (p1 == p3)
std::cout << "Point p1 == Point p3" << std::endl;
else
std::cout << "Point p1 != Point p3" << std::endl;
}
主文件
#pragma once
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <time.h>
#include "Tests.hpp"
int PRIME = 29;
void main()
{/*
Value a = 4;
Value b = 20;
std::vector<Point> allPoints = findAllPoints(a, b);
/*
// Tests ausfuehren
twoDAdd(a, b);
twoDDoubling(a, b);
threeDAdd(a, b);
threeDDoubling(a, b);
*/
std::cout << std::endl;
system("pause");
}
在此先感谢,请原谅我“不完美”的编码方式。