Page 1 of 1

Control calculator expression logic

Posted: Mon Aug 06, 2007 5:21 am
by keenlearner
Hello I am building a PHP scientific calculator, users can perform calculation by just typing like normal mathematical expressions, e.g "(2+3-4^6)/33.3* 4!" so the result will be calculated accordingly, but I have a problem that, when malicious users try to put a mathematical expressions that is very long enough and takes a very heavy load of processing which make may Apache server hang. Such as

"99999999999999 * 99999999999999 ^ 99999999999999999999999999 * 999999999999999999999999999999"

So I thought of limiting the expressions that users can input up to 30 characters long, but this is still not a good idea, because heavy calculations does not necessarily depends on the length of the expressions, such as

//This does not make my computer load heavily even though it's long because it's a simple calculations
"1+1+2+1+2+1+1+1+1+1+3+1+3+1+1+1+1+2+1+1+1+1+3+1+1+1+2+1+1+1+1+1+1+1+1+1+1+1+1+1+2"

//But this one consume high processing power and make my Apache server hang even it's short
"999999999^99999"

I did not use eval(), but BCMath function instead. For expressions like (2+3-4^6)/33.3* 4!, I use shunting yard algorithm

So I want to know, is there a logic that can actually determines the result which might consume high processing ? Thanks a lot.

Posted: Mon Aug 06, 2007 5:26 am
by iknownothing
I'm not sure if theres any logic for deciding whether or not something is going to take up a large amount of resources (as each server varies anyway), but you could use Javascript to limit the amount of values entered in after an operator that may use up large resources (eg. ^). It might be a tedious task to go through all the operators 1 by 1 however.

Posted: Mon Aug 06, 2007 5:41 am
by keenlearner
I believe there must be logic, because you can try in Google, type "99^154", it gives you result of calculation, but if you tried "99^155" . Google won't give you the result, because it seems that they will not calculate expression that will give result that exceed around 1e307.

I have tried out a lots of way, one of it

Let's say 999^999 will make my apache server hang, let the base and the power be x and y respectively, x ^ y
So if I limit the x and y to be 900 respectively, 900^900, so the the following should be OK
800^400
700^900

But problem is, this line below should be allowed too, because the result still less than 900^900 and does not load heavily.

2^1000

But since we limit the y to be 900, this will not be calculated, which is a bad idea too. Thanks.

Posted: Mon Aug 06, 2007 6:17 am
by feyd
There are math expression engines available which include many constants/functions which operate quite quickly.

Posted: Mon Aug 06, 2007 6:24 am
by keenlearner
Thanks for the reply, the matter is I am using BCmath which can caculate extremely fast already, but you might want to tried out, :wink: at your own risk, see what happen.

Code: Select all

<?php
echo bcpow(999,9999999);
?>

Posted: Mon Aug 06, 2007 6:59 am
by feyd
I've done plenty of work in bcmath; I know how it operates. This is why I recommend using an existing math expression engine.

Posted: Mon Aug 06, 2007 7:32 am
by keenlearner
Thanks and sorry that I don't get it before looking at math expression engine. It's a new term for me. But can you recommend one math expressions engine that is good and free ? :) So that I can embed into my PHP application. Thanks.