keenlearner Posted August 5, 2007 Share Posted August 5, 2007 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 might make my web server down. Such as "9999999999999999999999999999999999999999999999999999999 * 999999999999999999999999999999" So I thought of limiting the expressions that users can input up to 50 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 "1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1" //But this one takes quite long and consume high processing power. "999999999^99999" So I want to know, is there a logic that can actually determines the result which might consume high processing which can solve my problem ? or is there a good scientific calculator library that you might want to share ? Thanks a lot. Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/ Share on other sites More sharing options...
teng84 Posted August 5, 2007 Share Posted August 5, 2007 i see the prob but you can have it work using a nested IF i dodnt see any dificulties with this it will only need to have lot of filtering Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316254 Share on other sites More sharing options...
Barand Posted August 5, 2007 Share Posted August 5, 2007 Seems like you need to limit the numbers between certain operators and not the whole expression Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316255 Share on other sites More sharing options...
keenlearner Posted August 5, 2007 Author Share Posted August 5, 2007 Thanks, for the reply When I tried it on my localhost, "9999999^9999999999999999999" it really makes my processors lights on without blinking for quite a few seconds and finally makes my apache hang for 1.83 Ghz Duo core processors with 1.5 GB RAM. I believe there must be logic, because you can try in Google, type "999^99", it gives you result of calculation, but if you tried "999^103" . Google won't give you the result, because it seems that they will not calculate expression that will give result that exceed around 9.02983468 × 10^305 teng84, I have tried a few nested if, but seems that I still can't get the logic close to perfect yet, can you give me a brief algorithm for that ? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316264 Share on other sites More sharing options...
cooldude832 Posted August 5, 2007 Share Posted August 5, 2007 what you could do is apply some javascript to it first don't let the user edit the calculation area (make a javascript onfocus event to blur it) secondly if someone tries to calculate a ridiculous number like 99^99^99 in the coding do a test if the answer is greater than what max size is for a float. if that is the case tell it to break right away and give an overflow error. Also make t so they dont' have direct input make buttons like a calculator (you can use hotkeys too to get that feel too). Also maybe you could use ajaxs to test the output as they are inputting to test for overflows before it goes to that point (i.e 99^99 and they try to enter another ^99 say overflow.) Just a few ideas Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316268 Share on other sites More sharing options...
keenlearner Posted August 5, 2007 Author Share Posted August 5, 2007 How if expression that has only one operator 99^999 and also its result is too big to be handled. It's important that we need to decide whether the expressions is too be to be handled BEFORE the calculation is made, because if we can only decide whether to calculate the expression or not AFTER the calculation is made our Apache server already hang. I think it goes the same for browser as well, instead of making our Apache hang, it will make the users browser hang. I have tried something out below but still not solving. 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 2^900 since x or y are equal or less than 900 But problem is this line below should be allowed too, because the result still less than 900^900 and does not make heavy load. 2^1000 But since we limit the y to be 900, this will not be calculated, which is a bad idea too. I so eager to solve this, but so far have not get a good solutions, but I believe there is a logic like Google's. Thanks. Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316283 Share on other sites More sharing options...
cooldude832 Posted August 5, 2007 Share Posted August 5, 2007 set a pair of thresholds amounts for y/x (and secondary thresholds) i.e <?php $ymax = 999; $xmax = 99999; $ymax_2 = 9999; $xmax2 = 9999; if($_POST['x'] > $xmax){if($_POST['y'] >$ymax_2){//overflow}} ?> get the idea? Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316293 Share on other sites More sharing options...
cooldude832 Posted August 5, 2007 Share Posted August 5, 2007 set a pair of thresholds amounts for y/x (and secondary thresholds) i.e <?php $ymax = 999; $xmax = 99999; $ymax_2 = 9999; $xmax2 = 9999; if($_POST['x'] > $xmax){if($_POST['y'] >$ymax_2){//overflow}} ?> Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316299 Share on other sites More sharing options...
Barand Posted August 5, 2007 Share Posted August 5, 2007 if 2^1000 is OK but 999^1000 is not OK then for each x you need an upper y threshold Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316309 Share on other sites More sharing options...
keenlearner Posted August 6, 2007 Author Share Posted August 6, 2007 Thanks cooldude832, that is what I did initially but still not solving the problem if $xmax = 900; $ymax = 900; if($_GET['x'] > $xmax && $_GET['y'] > $ ymax) //overflow //But we should allowed if $_GET['x'] = 2 $_GET['y'] = 1000; //because this calculation still ok. I think the solutions might be something closed to Barand's, but so still we need to type a lot of threshold number (thousands) if 2^1000 is OK but 999^1000 is not OK then for each x you need an upper y threshold But I bet there is a formula to determine the heavy calculations, of it. Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316543 Share on other sites More sharing options...
Barand Posted August 6, 2007 Share Posted August 6, 2007 <?php function safePow($x, $y) { $r = pow($x,$y); return $r < 1.79e308 ? $r : 'overflow!'; } $expr = '2^99'; list ($x, $y) = explode('^', $expr); echo safePow ($x, $y); ?> Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316559 Share on other sites More sharing options...
keenlearner Posted August 6, 2007 Author Share Posted August 6, 2007 Thanks Barand, I am still looking up for solutions until now. It's important that we need to decide whether the expressions is too big to be handled BEFORE the calculation is made, because if we can only decide whether to calculate the expression AFTER the calculation is made, our Apache server will/already hang. <?php function safePow($x, $y) { $r = pow($x,$y); return $r < 1.79e308 ? $r : 'overflow!'; } //if we check whether this is safePow echo safePow(999, 9999999999999); //my apache server could already hang before it return the result. ?> I still believe there is a formula. Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316574 Share on other sites More sharing options...
Barand Posted August 6, 2007 Share Posted August 6, 2007 Suggest change of server <?php function safePow($x, $y) { $r = pow($x,$y); return $r < 1.79e308 ? $r : 'overflow!'; } $inputs = array ( '999^9999999999999', '2^9999', '99^99', '9^9' ); echo '<pre>'; printf ("\n%-20s : %25s : %8s\n", 'expression', 'result', 'seconds'); printf ("\n%-20s : %25s : %8s\n", '--------------------', '-------------------------', '--------'); foreach ($inputs as $expr) { list ($x, $y) = explode('^', $expr); $t1 = microtime(1); $p = safePow ($x, $y); $t2 = microtime(1); printf ("\n%-20s : %25s : %0.6f\n", $expr, $p, $t2-$t1); } echo '</pre>'; ?> Results -->[pre] expression : result : seconds -------------------- : ------------------------- : -------- 999^9999999999999 : overflow! : 0.000097 2^9999 : overflow! : 0.000025 99^99 : 3.6972963765E+197 : 0.000020 9^9 : 387420489 : 0.000019 [/pre] Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316590 Share on other sites More sharing options...
keenlearner Posted August 6, 2007 Author Share Posted August 6, 2007 You cannot use pow function to calculated pow(999,9999999999999); because it does not actually calculate but instead gives you the word "INF", because pow() cannot handle big number. try <?php echo pow(999,9999999999999); //gives INF ?> should use bcpow instead, try at your own risk. you will either have execution timeout or slow down your computer <?php echo bcpow(999,9999999); ?> That mean, php code itself has the logic that actually determines the number that is too big to be processed, as I just discovered about pow() will give INF, if the number is too big. Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316611 Share on other sites More sharing options...
Barand Posted August 6, 2007 Share Posted August 6, 2007 I was aware of the INF, which is why I was testing against 1.79e308 which is about as big as a float type will store. I changed to bcpow(). The one that didn't work (999^9999999999999) took only 0.000089 secs to give a result of 1 <?php function safePow($x, $y) { $r = bcpow($x,$y); return $r ? $r : 'overflow!'; } $inputs = array ( '999^9999999999999', '9^9999', '99^99', '9^9' ); echo '<table border="1">'; echo '<tr><td>expression</td><td>result</td><td>seconds</td></tr>'; foreach ($inputs as $expr) { list ($x, $y) = explode('^', $expr); $t1 = microtime(1); $p = safePow ($x, $y); $t2 = microtime(1); $t = sprintf ("%0.6f", $t2-$t1); $p = wordwrap ($p, 50, '<br/>', true); echo "<tr valign='top'><td>$expr</td><td>$p</td><td>$t</td></tr>"; } echo '</table>'; results --> expression | result | seconds ------------------+-------------------------------------------------------+--------- 999^9999999999999 | 1 | 0.000089 ------------------+-------------------------------------------------------+--------- 9^9999 | 29570038080193553244202241247182381904736703321559 | 0.080060 | 61671705236976632770045817648617101476387353131190 | 07794052755117226772246089286497411108107780037148 36325316042186166990796173111553392470503228770292 61635989747700682249026677170831101015638735481375 95348355198673095302780092160210144684226186834160 85201240881900696792962780195582937398604502704630 94178175710226111789638385298302727708698135607646 65235046072981883231569495823001414324280338228407 28160709641694694631974768106968066157416761673042 02328890013016792519047059316388947963396365040198 96529711440442278951154589236175839216922714879594 78105314259597356800173880535562903333968558439558 31297121192085529060174977473248308137087153677930 71364132861688345782900934182722384808424867747555 41216912068813554389615477881034622307250708201099 94431060541511605790633487375591189689906388924528 93300179055780332398687922375940465628910002345704 80466714010999453530847119757231540057030904501661 98577327065684255831398416277202011129243988044895 73400327530247339138349749900220177647606366946573 53730216426495327531084479505061474803804732314821 60428310852126756801840282958821614403826580523054 77466231671299300660555985531575924896657182021175 66661312585309037516052129309448917931270523260917 50397294686425312669136438517283705639333635161448 63290378253471075494974011148522354778328803663379 96240797554262456425498262419217851488935965187810 76168138576119458515712650610822442439090441062500 44113272115363110880072240671612230416702006619414 92645863388106811833930148937860388331508538314380 42873005007677566690968712353120167119136011921758 75017072784648797925283213179757572118877572888646 91395808200589001779854265847570611022274694232573 90096799491231413307181862194535751257149330940150 66400756969653201492693518526616493922350507786584 97673682783702780921253995141030624954339652548192 95393213833318985817405494470930042775903862323835 29490520380924489826502595909379268407809068495430 78295742149516334088901540757903467420116929759740 76534000673955772995699451999491338363638017711082 30954938187823919329366696142989020412803487266149 84850834485233646361804743009899859708625059629383 11674479728774599420881723382498918334543508882434 64187988269904342984965717714939722354428821288213 09527093860441661061595020273963143689053752482859 63936980732859377097888547029703382539875128459031 46538460377310130411666242532795708504730185811213 97059634128992476605199470753609284601349842100514 65187947556589536972458224443928196052506806800421 27864285303583940764887965608565264532864657900382 63980955744560865625661093634746457202552213684457 67218182971678242672700204741939223930082354521253 00222023701601954453307836514318910917610929735203 38839147013827757400238179104442275472661714530715 28314286523805302309338757786902507391827366919491 12323419677170157645740351158296240212392164022320 27147112072565950900550711954318831286711688187370 88668110998845593704678268546868364808547287745826 21929749433414187800946557466808865967459480128655 99992266034667429228735904479455139666557247545538 68723083531377146248270232328955912981277312653415 10500237430610563506505871436746090865505024769877 20690212456531379547297168100561437791860423543993 34819778335068866891940081581283566316826139345505 75772544811446899008048645133069410065779496114655 72940022955061091010981022280645044953998958131993 83140362526877321767588200080453523347221876232060 20977723735893520294435972552608047662861343949125 40998684180555769384208029934015945625879466674973 54580034100878934068922362224033987662029301109686 37013649286539563686221682799513491103221055267875 31670781652750939856398657730408147642156017685352 83091418223000778368198758730099085802982576706272 02566731856575447925528647565011072736397339253202 63530866879991279199727260917164090022389800696661 55440666237417330569446556830163261542217640716688 15802337723435233341864067753376358066733427906396 51806227129252424045577693626753414349694553699940 16324900652514820452041020190485994283561308228193 83215320896395201817996745130192490082374495742796 75032848026951246175575505494642028127562838850097 17518969113802602883749049237207848319884198177306 75355820044018456957224474538897254521899086006023 69908861169419639699252646556010477630410083621544 21800362587926918683479296388992290147447918992936 71954775292837970632891744369329225665456633647113 14940699390542611625491987237864525818027204029745 14276170009361596609951352538076687203591054857037 37764641160561004153147564890759752968370573145670 45244255224443934646752230285478698788583762905771 91311423776291450033842693858724965158971637408818 74511247861926996949148681631052746012920651998607 87757572337838800795758305342602393333453008108349 88061753580653973478481713273658376586045220698539 87296629979634483265168466126486656674100642477664 58362670505426949493400466925584610160801681424204 45518526975564707890297819149422961818016010278625 61156932177648731060005098555165982301669224850619 31568418920421355730198372688770124704040649788955 31438401781892885451830820475344582943588328787990 89702256206840837057621691373677297639204219764367 10390032384197426163185263705519853731224531526467 40199270943186176118773393258200652580755961531465 70111902415474720111355329099573858820008123215899 93409902299047644525884965566791214257881192183555 96560699411570242343224891700923733551004601621963 50647151185551009590044288630423722631130969833699 32095934486594530062522579603482790558852761178379 47706284338089146722288401310474129753706851522975 93223797168166886418233019849079025095866318576877 80589880079652470916876025997575067773343562654605 31519379224476760834134234614337155880766653056224 59042596271560541842680817113614874580945233962129 70850052054571809822955705308460844030980144613065 39038751616349875577937971988307916080587220999885 67176868301435233796114274654236143073061748492156 57378385500916228222233592211545032152971682739774 81932928515966598599881575645026192241899644769484 81057830334181859083884726990653893257863093033145 80466486624134047653822459616014565218780841269642 04969082985387993542747443683912121693609129050354 63503887221310426401072643059310377211093931497697 57313249399911667699014063033275135817872967642187 42991943899056501942281109105499183267310842559448 40757732465283833087086198490814260532804832246413 88400430414079610039997955092964197683584100478829 21701088855764446976283613408020402969743563282672 89263385534344933206093435043737406363387886774869 21840423163922011229387040507612715036528952537556 24071018124031544019780278375688474721324500890758 42359161812680573314811223726276185013514182917810 82016785907223723490432667679470198967192763318889 59442231412043052919197727234912153410925696239271 32343452090040857932178859516543294751009900505275 30887039823706933636042779991779742739205913916892 47905034203532233141572086180763614669296885421935 68683803813200508192423140834455476453713361942210 67383731457128363664501360900423116580376502116706 68634091277267329794431602831293750164739290568599 39588295163470442481839947092842780139819284350124 66404034216317441390796316558933151256466299953910 69898305785477084007456923291302412793544098044804 80482252229316720937807095113464188594976010910805 77947853968788958839298868031998145923655620055867 67697088148727353357253406583388718594467716018460 03008416768360925124349953243535737817566871351785 22370512103461402180355083036748951420840322767530 85370707124107923222070048543185429022365548997680 12384617201603334228446019920389903628378200620348 05625031849942629136028963224763264918594291058132 33575483058172466272591950184048879884196880599905 83398372192674712625256466264811150057048674429726 68051862965551403768012558261258797141909374946256 08082074450698191402160459983481261291146898169015 93744670125532544675101521226081281185262051430026 28567763911205058981484089445063925312227297156574 81951581522670526449606018798445937294460915663357 46323504396391888420611213053955019492234570426022 89040822345435531431410292004367782317582244666934 73423046999208799648215179733581316614051835295877 86552123805417707087326237259945875570517388086903 93647783463838973619031375364955834992555598419585 93680865189109754700833125514749997252298276449644 08532107884666557244757362336353067996857134986514 95985416152932810517582073377481192674721483835033 51817947851292651019626542119198731125390244483065 42130152497845627886758210063819409277278037971390 22846222722392173144911498124622263762556297135799 12991476187783467147893547560740494329605275322184 72847758596800711647195207815846432905338351479722 76625783445031054465600606029383933811394144549916 75399051033257520096512262404228163918778716613969 71050272517627382736126624668252876766658122078227 91553099424225902561578601700094217249553393903866 52393523143979523187416086683508300247975052291717 42439849381576402557448811144234328562782819535722 44699693718421884209408629980999899657811805537222 47371772149023528051050125766868603163822501525756 01425820418297597111429171696692836924331763474919 75784425336398994743098294658517001590759607096696 80989681019942501232514157563343960774110382841718 45379848297363851751878210438439229169184979216267 33246346349488728012465502515835727748075661320440 94225581352181360560295400258287887763614409248206 10516131547281258707684177763777809520979886388927 56560559992172866846718663746826331406030145201705 24514241384392975281951062730998080957582038094340 05465349443547202137623711977961945635153179851222 | 39306227452805339194206261922327328881385264946493 | | 107731598333726490360478756392805900488889 | ------------------+-------------------------------------------------------+--------- 99^99 | 36972963764972677265718790562880544059566876428174 | 0.000168 | 11024302599724235525704552775234214106500101282327 | | 27940978889548326540119429996769494359451621570193 | | 644014418071060667659301384999779999159200499899 | ------------------+-------------------------------------------------------+--------- 9^9 | 387420489 | 0.000024 Quote Link to comment https://forums.phpfreaks.com/topic/63457-control-calculator-expression-logic/#findComment-316758 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.