Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Miller-Rabin素性测试FIPS 186-3的实现_C++_Math_Implementation_Primality Test - Fatal编程技术网

C++ Miller-Rabin素性测试FIPS 186-3的实现

C++ Miller-Rabin素性测试FIPS 186-3的实现,c++,math,implementation,primality-test,C++,Math,Implementation,Primality Test,我试图根据C.3.1中的描述实施Miller-Rabin素性测试。不管我做什么,我都不能让它工作。说明非常具体,我不认为我遗漏了什么,但是我得到了非素数值的true 我做错了什么 template <typename R, typename S, typename T> T POW(R base, S exponent, const T mod){ T result = 1; while (exponent){ if (exponent & 1

我试图根据C.3.1中的描述实施Miller-Rabin素性测试。不管我做什么,我都不能让它工作。说明非常具体,我不认为我遗漏了什么,但是我得到了非素数值的
true

我做错了什么

template <typename R, typename S, typename T>
T POW(R base, S exponent, const T mod){
    T result = 1;
    while (exponent){
        if (exponent & 1)
            result = (result * base) % mod;
        exponent >>= 1;
        base = (base * base) % mod;
    }
    return result;
}



// used uint64_t to prevent overflow, but only testing with small numbers for now
bool MillerRabin_FIPS186(uint64_t w, unsigned int iterations = 50){
    srand(time(0));
    unsigned int a = 0;
    uint64_t W = w - 1; // dont want to keep calculating w - 1
    uint64_t m = W;
    while (!(m & 1)){
        m >>= 1;
        a++;
    }

    // skipped getting wlen
    // when i had this function using my custom arbitrary precision integer class,
    // and could get len(w), getting it and using it in an actual RBG 
    // made no difference 

    for(unsigned int i = 0; i < iterations; i++){
        uint64_t b = (rand() % (W - 3)) + 2; // 2 <= b <= w - 2
        uint64_t z = POW(b, m, w);
        if ((z == 1) || (z == W))
            continue;
        else
            for(unsigned int j = 1; j < a; j++){
                z = POW(z, 2, w);
                if (z == W)
                    continue;
                if (z == 1)
                    return 0;// Composite
            }
    }
    return 1;// Probably Prime
}

您的实现与Wikipedia的唯一区别在于您忘记了第二条return复合语句。在循环的末尾应该有一个返回0

编辑:正如丹尼尔所指出的,还有第二个区别。continue是继续内部循环,而不是像它应该的那样继续外部循环

for(unsigned int i = 0; i < iterations; i++){
    uint64_t b = (rand() % (W - 3)) + 2; // 2 <= b <= w - 2
    uint64_t z = POW(b, m, w);
    if ((z == 1) || (z == W))
        continue;
    else{
        int continueOuter = 0;
        for(unsigned int j = 1; j < a; j++){
            z = POW(z, 2, w);
            if (z == W)
                continueOuter = 1;
                break;
            if (z == 1)
                return 0;// Composite
        }
        if (continueOuter) {continue;}
    }
    return 0; //This is the line you're missing.
}
return 1;// Probably Prime
for(无符号整数i=0;i
        for(unsigned int j = 1; j < a; j++){
            z = POW(z, 2, w);
            if (z == W)
                continue;
            if (z == 1)
                return 0;// Composite
        }
for(无符号整数j=1;j

z==W
时,你应该
break;
而不是
continue;
z==W
时。通过
continue
ing,在该循环的下一次迭代中,如果有一个循环,
z
将变为1,候选循环可能被错误地声明为复合循环。这里,对于小于100的素数中的17、41、73、89和97,会发生这种情况。

请看
POW
?我看到一个错误,它可能会将一些素数声明为复合数,但没有任何东西会从另一个方向跳出来。对于哪些值,您得到了错误的结果?您对POW的定义在哪里?POW很好,但我会在任何情况下给出它。顺便说一句,您的随机数是--模运算会扭曲结果。如果
res怎么办ult*base
base*base
溢出?希望对偶数不使用素性测试。:)哦,拜托,这当然不值得投反对票……这是一个很好的观点。:)为什么投反对票?这是一个合理的问题,我写这篇文章时不知道测试了什么数字。现在我得到了0,我加了一个将
{}
返回给else,因此它不会在1之后返回0iteration@calccrypto:您不能只添加中断和返回0,因为现在每当您中断返回0时,都会触发。请在循环之前将标志(例如contloop)设置为false。设置“contloop=1;break;}而不是仅中断,然后仅在contloop为false时返回0。[或其他什么]啊,就在我正要点击send的时候。我认为如果这个循环一直通过,那么这个和返回0都是必要的。哇,我不敢相信我错过了。continue只是继续内部循环,而不是应该继续的外部循环。
for(unsigned int i = 0; i < iterations; i++){
    uint64_t b = (rand() % (W - 3)) + 2; // 2 <= b <= w - 2
    uint64_t z = POW(b, m, w);
    if ((z == 1) || (z == W))
        continue;
    else{
        int continueOuter = 0;
        for(unsigned int j = 1; j < a; j++){
            z = POW(z, 2, w);
            if (z == W)
                continueOuter = 1;
                break;
            if (z == 1)
                return 0;// Composite
        }
        if (continueOuter) {continue;}
    }
    return 0; //This is the line you're missing.
}
return 1;// Probably Prime
        for(unsigned int j = 1; j < a; j++){
            z = POW(z, 2, w);
            if (z == W)
                continue;
            if (z == 1)
                return 0;// Composite
        }