Miller–Rabin primality test: Difference between revisions
Content added Content deleted
(Added Kotlin) |
m (→Using Big Integer library: changed the way the random generator is seeded) |
||
Line 1,644: | Line 1,644: | ||
===Using Big Integer library=== |
===Using Big Integer library=== |
||
{{libheader|GMP}} |
{{libheader|GMP}} |
||
<lang freebasic>' version |
<lang freebasic>' version 05-04-2017 |
||
' compile with: fbc -s console |
' compile with: fbc -s console |
||
Line 1,650: | Line 1,650: | ||
' But we have to define them for older versions. |
' But we have to define them for older versions. |
||
#Ifndef TRUE |
#Ifndef TRUE |
||
#Define FALSE 0 |
#Define FALSE 0 |
||
#Define TRUE Not FALSE |
#Define TRUE Not FALSE |
||
#EndIf |
#EndIf |
||
Line 1,661: | Line 1,661: | ||
#EndMacro |
#EndMacro |
||
Dim Shared As __gmp_randstate_struct |
Dim Shared As __gmp_randstate_struct rnd_ |
||
Function miller_rabin(big_n As Mpz_ptr, num_of_tests As ULong) As Byte |
Function miller_rabin(big_n As Mpz_ptr, num_of_tests As ULong) As Byte |
||
#Macro cleanup |
|||
⚫ | |||
⚫ | |||
#EndMacro |
|||
If mpz_cmp_ui(big_n, 1) < |
If mpz_cmp_ui(big_n, 1) < 1 Then |
||
Print " |
Print "Numbers smaller then 1 not allowed" |
||
Sleep 5000 |
Sleep 5000 |
||
End If |
End If |
||
Line 1,682: | Line 1,677: | ||
Dim As ULong r, s |
Dim As ULong r, s |
||
Dim As Byte return_value = TRUE |
|||
big_int(n_1) : big_int(n_2) : big_int(a) : big_int(d) : big_int(x) |
big_int(n_1) : big_int(n_2) : big_int(a) : big_int(d) : big_int(x) |
||
Line 1,688: | Line 1,685: | ||
While mpz_tstbit(d, 0) = 0 |
While mpz_tstbit(d, 0) = 0 |
||
mpz_fdiv_q_2exp(d, d, 1) |
mpz_fdiv_q_2exp(d, d, 1) |
||
s = |
s += 1 |
||
Wend |
Wend |
||
While num_of_tests > 0 |
While num_of_tests > 0 |
||
num_of_tests -= 1 |
num_of_tests -= 1 |
||
mpz_urandomm(a, @ |
mpz_urandomm(a, @rnd_, n_2) |
||
mpz_add_ui(a, a, 2) |
mpz_add_ui(a, a, 2) |
||
mpz_powm(x, a, d, big_n) |
mpz_powm(x, a, d, big_n) |
||
Line 1,701: | Line 1,698: | ||
mpz_powm_ui(x, x, 2, big_n) |
mpz_powm_ui(x, x, 2, big_n) |
||
If mpz_cmp_ui(x, 1) = 0 Then |
If mpz_cmp_ui(x, 1) = 0 Then |
||
return_value = FALSE |
|||
Exit While |
|||
End If |
End If |
||
If mpz_cmp(x, n_1) = 0 Then Continue While |
If mpz_cmp(x, n_1) = 0 Then Continue While |
||
Line 1,708: | Line 1,705: | ||
If mpz_cmp(x, n_1) <> 0 Then |
If mpz_cmp(x, n_1) <> 0 Then |
||
Return_value = FALSE |
|||
Exit while |
|||
End If |
End If |
||
Wend |
Wend |
||
⚫ | |||
cleanup |
|||
⚫ | |||
⚫ | |||
⚫ | |||
End Function |
End Function |
||
' ------=< MAIN >=------ |
' ------=< MAIN >=------ |
||
⚫ | |||
⚫ | |||
Dim As String tmp |
|||
⚫ | |||
big_int(big_n) |
big_int(big_n) |
||
Randomize Timer |
Randomize Timer |
||
gmp_randinit_mt(@ |
gmp_randinit_mt(@rnd_) |
||
For x = 0 To 200 'create seed for random generator |
|||
tmp += Str(Int(Rnd * 10)) |
|||
Next |
|||
Mpz_set_str(big_n, tmp, 10) |
|||
gmp_randseed(@rnd_, big_n) ' seed the random number generator |
|||
⚫ | |||
For x = 2 To 100 |
For x = 2 To 100 |
||
mpz_set_ui(big_n, x) |
mpz_set_ui(big_n, x) |
||
Line 1,739: | Line 1,743: | ||
mpz_set_ui(big_n, 1) |
mpz_set_ui(big_n, 1) |
||
mpz_mul_2exp(big_n, big_n, x) |
mpz_mul_2exp(big_n, big_n, x) |
||
mpz_sub_ui(big_n,big_n,1) |
mpz_sub_ui(big_n, big_n, 1) |
||
If miller_rabin(big_n, 5) = TRUE Then |
If miller_rabin(big_n, 5) = TRUE Then |
||
gmp_str = Mpz_get_str(0, 10, big_n) |
gmp_str = Mpz_get_str(0, 10, big_n) |
||
Line 1,746: | Line 1,750: | ||
Next |
Next |
||
⚫ | |||
Print |
|||
⚫ | |||
mpz_clear(big_n) |
mpz_clear(big_n) |
||
DeAllocate(gmp_str) |
DeAllocate(gmp_str) |
||
' empty keyboard buffer |
' empty keyboard buffer |
||
While |
Print : While Inkey <> "" : Wend |
||
Print : Print "hit any key to end program" |
Print : Print "hit any key to end program" |
||
Sleep |
Sleep |