I have what I believe is a proper implementation of the miller-rabin algorithm using Lua, and I am trying to get a consistent return for prime numbers. It seems my implementation only works half of the time. Although if I try implementing similar code within python, that code works 100% of the time. Could someone point me in the right direction?
--decompose n-1 as (2^s)*d
local function decompose(negOne)
exponent, remainder = 0, negOne
while (remainder%2) == 0 do
exponent = exponent+1
remainder = remainder/2
end
assert((2^exponent)*remainder == negOne and ((remainder%2) == 1), "Error setting up s and d value")
return exponent, remainder
end
local function isNotWitness(n, possibleWitness, exponent, remainder)
witness = (possibleWitness^remainder)%n
if (witness == 1) or (witness == n-1) then
return false
end
for _=0, exponent do
witness = (witness^2)%n
if witness == (n-1) then
return false
end
end
return true
end
--using miller-rabin primality testing
--n the integer to be tested, k the accuracy of the test
local function isProbablyPrime(n, accuracy)
if n <= 3 then
return n == 2 or n == 3
end
if (n%2) == 0 then
return false
end
exponent, remainder = decompose(n-1)
--checks if it is composite
for i=0, accuracy do
math.randomseed(os.time())
witness = math.random(2, n - 2)
if isNotWitness(n, witness, exponent, remainder) then
return false
end
end
--probably prime
return true
end
if isProbablyPrime(31, 30) then
print("prime")
else
print("nope")
end
Python has arbitrary length integers. Lua doesn't.
The problem is in witness = (possibleWitness^remainder)%n.
Lua is unable to calculate exact result of 29^15 % 31 directly.
There is a workaround working for numbers n < sqrt(2^53):
witness = mulmod(possibleWitness, remainder, n)
where
local function mulmod(a, e, m)
local result = 1
while e > 0 do
if e % 2 == 1 then
result = result * a % m
e = e - 1
end
e = e / 2
a = a * a % m
end
return result
end
Related
I'm trying to reverse a decode function. This function takes a string and a key and encodes the string with that key. This is the code:
function decode(key, code)
return (code:gsub("..", function(h)
return string.char((tonumber(h, 16) + 256 - 13 - key + 255999744) % 256)
end))
end
If I input 7A as code and 9990 as key, it returns g
I tried reversing the operators and fed back the output of the decode function but I get an error becauase tonumber() returns nil. How can I reverse this function?
By using the answer to this Lua base coverter and flipping the operators of the decode function, I was able to convert back the input.
This is the whole code:
function encodes(key, code)
return (code:gsub("..", function(h)
return string.char((tonumber(h, 16) + 256 - 13 - key + 255999744) % 256)
end))
end
local floor,insert = math.floor, table.insert
function basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
local sign = ""
if n < 0 then
sign = "-"
n = -n
end
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return sign .. table.concat(t,"")
end
function decodes(key, code)
return (code:gsub(".", function(h)
out = (string.byte(h) - 256 + 13 + key - 255999744) % 256
return basen(out,16)
end))
end
a = encodes(9999, "7c7A")
print(a) --prints: `^
print("----------")
b = decodes(9999, a)
print(b) --prints: 7C7A
I am working on some assembly program analysis task using Z3. And I am trapped in simulating the semantics of x86 opcode bsf.
The semantics of bsf operand1 operand2 is defined as searches the source operand (operand1) for the least significant set bit (1 bit).
Its semantics can be simulated in C as:
if(operand1 == 0) {
ZF = 0;
operand2 = Undefined;
}
else {
ZF = 0;
Temporary = 0;
while(Bit(operand1, Temporary) == 0) {
Temporary = Temporary + 1;
operand2 = Temporary;
}
}
Right now, suppose each operand (e.g., register) maintains a symbolic expression, I am trying to simulate the above semantics in Z3Py. The code I wrote is something like this (simplified):
def aux_bsf(x): # x is operand1
if simplify(x == 0):
raise Exception("undefined in aux_bsf")
else:
n = x.size()
for i in range(n):
b = Extract(i, i, x)
if simplify(b == 1):
return BitVecVal(i, 32)
raise Exception("undefined in bsf")
However, I find that the evaluation of simplify(x==0) (e.g., x equals BitVecVal(13, 32) + BitVec("symbol1", 32),) is always equal to True. In other words, I am always trapped in the first exception!
Am I doing anything wrong here..?
====================================================
OK, so I think what I need is something like:
def aux_bsf(x):
def aux(x, i):
if i == 31:
return 31
else:
return If(Extract(i, i, x) == 1, i, aux(x, i+1))
return aux(x, 0)
simplify(x == 0) returns an expression, it does not return True/False, where False = 0. Python would treat an expression reference as a non-zero value and therefore take the first branch. Unless 'x' is a bit-vector constant, simplification would not return a definite value. The same issue is with simplify(b == 1).
You could encode such functions as a relation between operand1 and operand2, e.g., something along the lines of:
def aux_bsf(s, x, y):
for k in range(x.size()):
s.Add(Implies(lsb(k, x), y == k)
def lsb(k, x):
first0 = True
if k > 0:
first0 = Extract(x, k-1,0) == 0
return And(Extract(x,k,k) == 1, first0)
You can also use uninterpreted functions for the cases where aux_bsf is under-specified.
For example:
def aux_bsf(x):
bv = x.sort()
bsf_undef = Function('bsf-undef', bv, bv)
result = bsf_undef(x)
for k in reverse(range(bv.size()))
result = If(Extract(x, k, k) == 1), BitVecVal(k, bv), result)
return result
def reverse(xs):
....
I'm trying to calculate the sum of the prime numbers in a given number. For instance, for the number 123456, the result will be 10 because 2+3+5 = 10.
I tried to write a code that does that in Lua but I had some issues.
First, here is the code:
function isPrime(num)
if(num == 1 or (num ~= 2 and num%2 == 0)) then
return false
end
for i=3, math.sqrt(num), 2 do
if(num%i == 0) then
return false
end
end
return true
end
function sumOfPrimes(num)
local sum = 0
for digit in string.gmatch(num,"%d") do
local prime = isPrime(digit)
if(isPrime(digit)) then
sum = sum + digit
end
print(digit)
end
return sum
end
function main()
print(sumOfPrimes(123456))
end
main()
It returnes 9 instead of 10. Another thing I've noticed is it adds 1 also to sum, but 1 isn't a prime. What's the problem here?
string.gmatch returns a string, you need to convert it to number before doing calculations
Btw, you are doing the prime validation twice on your loop.
This is a fixed version (returns 10 as expected):
...
function sumOfPrimes(num)
local sum = 0
for digit in string.gmatch(num, "%d") do
digit = tonumber(digit) --needed conversion
local prime_digit = isPrime(digit)
if prime_digit then
sum = sum + digit
end
end
return sum
end
I'm currently getting familiar with the LPeg parser module. For this I want to match a version string (e.g. 11.4) against a list.
Such a list is a string with a tight syntax that can also contain ranges. Here is an EBNF-like, but in any case quite simple grammar (I write it down because LPeg code below can be a bit difficult to read):
S = R, { ',', R }
R = N, [ '-', N ]
N = digit+, [ '.', digit+ ]
An example string would be 1-9,10.1-11,12. Here is my enormous code:
local L = require "lpeg"
local LV, LP, LC, LR, floor = L.V, L.P, L.C, L.R, math.floor
local version = "7.25"
local function check(a, op, b)
if op and a+0 <= version and version <= b+0 then
return a..op..b -- range
elseif not op and floor(version) == floor(a+0) then
return a -- single item
end
end
local grammar = LP({ "S",
S = LV"R" * (LP"," * LV"R")^0,
R = LV"V" * (LC(LP"-") * LV"V")^-1 / check,
V = LC(LV"D" * (LP"." * LV"D")^-1),
D = (LR("09")^1),
})
function checkversion(str)
return grammar:match(str)
end
So you would call it like checkversion("1-7,8.1,8.3,9") and if the current version is not matched by the list you should get nil.
Now, the trouble is, if all calls to check return nothing (meaning, if the versions do not match), grammar:match(...) will actually have no captures and so return the current position of the string. But this is exactly what I do not want, I want checkversion to return nil or false if there is no match and something that evaluates to true otherwise, actually just like string:match would do.
If I on the other hand return false or nil from check in case of a non-match, I end up with return values from match like nil, "1", nil, nil which is basically impossible to handle.
Any ideas?
I think you can or + it with a constant capture of nil:
grammar = grammar + lpeg.Cc(nil)
This is the pattern I eventually used:
nil_capturing_pattern * lpeg.Cc(nil)
I incorporated it into the grammar in the S rule (Note that this also includes changed grammar to "correctly" determine version order, since in version numbering "4.7" < "4.11" is true, but not in calculus)
local Minor_mag = log10(Minor);
local function check(a, am, op, b, bm)
if op then
local mag = floor(max(log10(am), log10(bm), Minor_mag, 1))+1;
local a, b, v = a*10^mag+am, b*10^mag+bm, Major*10^mag+Minor;
if a <= v and v <= b then
return a..op..b;
end
elseif a == Major and (am == "0" or am == Minor) then
return a.."."..am;
end
end
local R, V, C, Cc = lpeg.R, lpeg.V, lpeg.C, lpeg.Cc
local g = lpeg.P({ "S",
S = V("R") * ("," * V("R"))^0 * Cc(nil),
R = (V("Vm") + V("VM")) * (C("-") * (V("Vm") + V("VM")))^-1 / check,
VM = V("D") * Cc("0"),
Vm = V("D") * "." * V("D"),
D = C(R("09")^1),
});
Multiple returns from match are not impossible to handle, if you catch them in a way that makes handling them easier. I added a function matched that does that, and added the fallback return of false to your check.
do
local L = require "lpeg"
local LV, LP, LC, LR, floor = L.V, L.P, L.C, L.R, math.floor
local version = 6.25
local function check(a, op, b)
if op and a+0 <= version and version <= b+0 then
return a..op..b -- range
elseif not op and floor(version) == floor(a+0) then
return a -- single item
end
return false
end
local grammar = LP({ "S",
S = LV"R" * (LP"," * LV"R")^0,
R = LV"V" * (LC(LP"-") * LV"V")^-1 / check,
V = LC(LV"D" * (LP"." * LV"D")^-1),
D = (LR("09")^1),
})
local function matched(...)
local n = select('#',...)
if n == 0 then return false end
for i=1,n do
if select(i,...) then return true end
end
return false
end
function checkversion(ver,str)
version = ver
return matched(grammar:match(str))
end
end
I enclosed the whole thing in do ... end so that the local version which is used here as an upvalue to check would have constrained scope, and added a parameter to checversion() to make it clearer to run through few test cases. For example:
cases = { 1, 6.25, 7.25, 8, 8.5, 10 }
for _,v in ipairs(cases) do
print(v, checkversion(v, "1-7,8.1,8.3,9"))
end
When run, I get:
C:\Users\Ross\Documents\tmp\SOQuestions>q18793493.lua
1 true
6.25 true
7.25 false
8 true
8.5 true
10 false
C:\Users\Ross\Documents\tmp\SOQuestions>
Note that either nil or false would work equally well in this case. It just feels saner to have collected a list that can be handled as a normal Lua array-like table without concern for the holes.
Here is my Lua code for taking user input, and checking if the number entered is prime. My issue is that the program thinks that any even number is not prime, and any odd number is.
print("Enter a number.")
local number = io.read("*n")
function prime(n)
for i = 2, n^(1/2) do
if (n % i) == 0 then
return false
end
return true
end
end
if prime(number) == true then
print("Your number is prime!")
end
if prime(number) == false then
print("Your number is not prime!")
end
Move return true out of the loop.
Hence:
function prime(n)
for i = 2, n^(1/2) do
if (n % i) == 0 then
return false
end
end
return true
end
You return true too soon. You return true as soon as any i meets the condition. You must place the return after the loop.
I know it's an old post but since it's near the top on google I figured it can't hurt to post up my prime finder. It basically does a few simple checks of the obvious stuff and then loops through whats left in a similar fashion to the first example in Jon Ericson' post. Haven't benchmarked it but it seems to cope well enough.
--returns true if prime
function isPrime(n)
local n = tonumber(n)
--catch nil, 0, 1, negative and non int numbers
if not n or n<2 or (n % 1 ~=0) then
return false
--catch even number above 2
elseif n>2 and (n % 2 == 0) then
return false
--primes over 5 end in 1,3,7 or 9
--catch numbers that end in 5 or 0 (multiples of 5)
elseif n>5 and (n % 5 ==0) then
return false
--now check for prime
else
--only do the odds
for i = 3, math.sqrt(n), 2 do
--did it divide evenly
if (n % i == 0) then
return false
end
end
--can defeat optimus
return true
end
end
If you are going to be checking primality, you might as well pick an efficient algorithm. As one answer (cryptically) pointed out, all even numbers greater than 2 are not prime. Therefore, you can short-circuit the check for half the numbers, which doubles the speed to check any particular number:
function check_prime (x)
-- Negative numbers, 0 and 1 are not prime.
if x < 2 then
return false
end
-- Primality for even numbers is easy.
if x == 2 then
return 2
end
if x%2 == 0 then
return false
end
-- Since we have already considered the even numbers,
-- see if the odd numbers are factors.
for i = 3, math.sqrt(x), 2 do
if x%i == 0 then
return false
end
end
return x
end
There are all sorts of optimizations we could apply, but let's take a shot at doing this in a more Lua manner:
function sieve (x)
if x < 2 then
return false
end
-- Assume all numbers are prime until proven not-prime.
local prime = {}
prime[1] = false
for i = 2, x do
prime[i] = true
end
-- For each prime we find, mark all multiples as not-prime.
for i = 2, math.sqrt(x) do
if prime[i] then
for j = i*i, x, i do
prime[j] = false
end
end
end
return prime
end
To use the sieve function:
prime = sieve(number)
if prime[number] then
print("Your number is prime!")
else
print("Your number is not prime!")
end
In my tests, the sieve version is about 6 times faster than the previous algorithm for generating all the primes less than 1 million. (Your mileage may vary.) You can easily check the primality of all numbers less than number at no extra cost. On the other hand, it uses more memory and if you really want check the primality of just one number, it's less efficient.
I would check for primes by dividing the number with 2 and checking if the floor of the division is equal to the division. It looks like this.
if (input/2 == math.floor(input/2)) then
print("is prime")
else
print("is not prime")
end