mirror of
https://github.com/danog/PrimeModule-ext.git
synced 2024-11-26 20:04:40 +01:00
100 lines
2.4 KiB
C++
100 lines
2.4 KiB
C++
|
/*
|
||
|
* This taken from the source code of tgnet library v. 1.0
|
||
|
* It is licensed under GNU GPL v. 2 or later.
|
||
|
* You should have received a copy of the license in this archive (see LICENSE).
|
||
|
*
|
||
|
* Copyright Nikolai Kudashov, 2015.
|
||
|
*/
|
||
|
|
||
|
#include <phpcpp.h>
|
||
|
|
||
|
|
||
|
inline uint64_t gcd(uint64_t a, uint64_t b) {
|
||
|
while (a != 0 && b != 0) {
|
||
|
while ((b & 1) == 0) {
|
||
|
b >>= 1;
|
||
|
}
|
||
|
while ((a & 1) == 0) {
|
||
|
a >>= 1;
|
||
|
}
|
||
|
if (a > b) {
|
||
|
a -= b;
|
||
|
} else {
|
||
|
b -= a;
|
||
|
}
|
||
|
}
|
||
|
return b == 0 ? a : b;
|
||
|
}
|
||
|
inline Php::Value factorize(Php::Parameters ¶meters)
|
||
|
{
|
||
|
uint64_t what = (int64_t) parameters[0];
|
||
|
uint32_t p;
|
||
|
uint32_t q;
|
||
|
int32_t it = 0, i, j;
|
||
|
uint64_t g = 0;
|
||
|
for (i = 0; i < 3 || it < 1000; i++) {
|
||
|
uint64_t t = ((lrand48() & 15) + 17) % what;
|
||
|
uint64_t x = (long long) lrand48() % (what - 1) + 1, y = x;
|
||
|
int32_t lim = 1 << (i + 18);
|
||
|
for (j = 1; j < lim; j++) {
|
||
|
++it;
|
||
|
uint64_t a = x, b = x, c = t;
|
||
|
while (b) {
|
||
|
if (b & 1) {
|
||
|
c += a;
|
||
|
if (c >= what) {
|
||
|
c -= what;
|
||
|
}
|
||
|
}
|
||
|
a += a;
|
||
|
if (a >= what) {
|
||
|
a -= what;
|
||
|
}
|
||
|
b >>= 1;
|
||
|
}
|
||
|
x = c;
|
||
|
uint64_t z = x < y ? what + x - y : x - y;
|
||
|
g = gcd(z, what);
|
||
|
if (g != 1) {
|
||
|
break;
|
||
|
}
|
||
|
if (!(j & (j - 1))) {
|
||
|
y = x;
|
||
|
}
|
||
|
}
|
||
|
if (g > 1 && g < what) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g > 1 && g < what) {
|
||
|
p = (uint32_t) g;
|
||
|
q = (uint32_t) (what / g);
|
||
|
if (p > q) {
|
||
|
uint32_t tmp = p;
|
||
|
p = q;
|
||
|
q = tmp;
|
||
|
}
|
||
|
Php::Value result;
|
||
|
result[0] = (int32_t) p;
|
||
|
result[1] = (int32_t) q;
|
||
|
return result;
|
||
|
} else {
|
||
|
throw Php::Exception("Factorization failed!");
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern "C" {
|
||
|
PHPCPP_EXPORT void *get_module() {
|
||
|
static Php::Extension extension("primemodule", "1.0");
|
||
|
extension.add<factorize>("factorize", {
|
||
|
Php::ByVal("pq", Php::Type::Numeric),
|
||
|
Php::ByRef("p", Php::Type::Numeric),
|
||
|
Php::ByRef("q", Php::Type::Numeric),
|
||
|
});
|
||
|
return extension;
|
||
|
}
|
||
|
}
|
||
|
|