Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Random F%^k up strings!

by marinersk (Priest)
on May 21, 2017 at 04:08 UTC ( [id://1190780]=note: print w/replies, xml ) Need Help??


in reply to Random F%^k up strings!

I'd lay good odds that randis not actually messing up your strings. You are probably making a mistake in the declaration of your variables.

Let's walk through the process.

I added one line to your code so we could see the results:

$randomNumber = int(rand(100)) +1; if ($randomNumber < 100 and $randomNumber > 50) { $answer = "kbNtA"; } else { $answer = "WiaNq"; } print "Answer = [$answer]\n";

It seems to be working fine:

S:\PerlMonks>perl scope0.pl Answer = [kbNtA] S:\PerlMonks>perl scope0.pl Answer = [kbNtA] S:\PerlMonks>perl scope0.pl Answer = [kbNtA] S:\PerlMonks>perl scope0.pl Answer = [kbNtA] S:\PerlMonks>perl scope0.pl Answer = [WiaNq]

However, you're not running strictand warnings, which are critical to avoid mistakes and many bad programming techniques. So I cleaned up the code a bit:

#!/usr/bin/perl use strict; use warnings; $randomNumber = int(rand(100)) +1; if ($randomNumber < 100 and $randomNumber > 50) { $answer = "kbNtA"; } else { $answer = "WiaNq"; } print "Answer = [$answer]\n";

That doesn't work so well, and the issues raised could be the source of your problem. (It's hard to tell since you clearly did not show enough code and data to reproduce the problem.)

S:\PerlMonks>perl scope2.pl Global symbol "$randomNumber" requires explicit package name at scope2 +.pl line 5. Global symbol "$randomNumber" requires explicit package name at scope2 +.pl line 6. Global symbol "$randomNumber" requires explicit package name at scope2 +.pl line 6. Global symbol "$answer" requires explicit package name at scope2.pl li +ne 7. Global symbol "$answer" requires explicit package name at scope2.pl li +ne 9. Global symbol "$answer" requires explicit package name at scope2.pl li +ne 11. Execution of scope2.pl aborted due to compilation errors. S:\PerlMonks>

So I cleaned up the errors:

#!/usr/bin/perl use strict; use warnings; my $answer = ''; my $randomNumber = int(rand(100)) +1; if ($randomNumber < 100 and $randomNumber > 50) { $answer = "kbNtA"; } else { $answer = "WiaNq"; } print "Answer = [$answer]\n";

And it seems to be working again:

S:\Steve\Dev\PerlMonks\P-2017-05-20@2349-Variable-Scope-Failure>perl s +cope3.pl Answer = [WiaNq] S:\Steve\Dev\PerlMonks\P-2017-05-20@2349-Variable-Scope-Failure>perl s +cope3.pl Answer = [WiaNq] S:\Steve\Dev\PerlMonks\P-2017-05-20@2349-Variable-Scope-Failure>perl s +cope3.pl Answer = [kbNtA]

I'd suggest using strictand warningsand declaring your variables with myand then re-run the script. I would not be surprised if Perl tells you what you're doing wrong.

Replies are listed 'Best First'.
Re^2: Random F%^k up strings!
by TroyH (Initiate) on May 22, 2017 at 00:29 UTC
    #!/usr/bin/perl use CGI qw/:html3 :standard/; use Fcntl qw/:flock/; # ################################################# # # # My Capcha # # # # Starting Date: April 20, 2017 # # Last Modified: May 21, 2017 # # # # Written by Troy Hammack # # Email: troylh@pacbell.net # # # ################################################# # # $ENV{"PATH"}=''; $ENV{"BASH_ENV"}=''; print "Content-type:text/html\n\n"; if ($ENV{'REQUEST_METHOD'} eq 'GET') { @pairs = split(/&/, $ENV{'QUERY_STRING'}); } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); } else { print "Content-type: text/html\n\n"; print "<P>Use Post or Get"; } foreach $pair (@pairs) { ($key, $value) = split (/=/, $pair); $key =~ tr/+/ /; $key =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~s/<!--(.|\n)*-->//g; if ($formdata{$key}) { $formdata{$key} .= ", $value"; } else { $formdata{$key} = $value; } # # Test to see if Reset button was selected and clear all values in the + keys # if ($formdata{'reset'} eq "Reset") { foreach $pair (@pairs) { ($key, $value) = split (/=/, $pair); $formdata{$key} = ""; } } # # The answer < -- If I use this it doesn't work! # my @chars = ("A".."Z", "a".."z"); my $answer; $answer .= $chars[rand @chars] for 0..4; # # $answer = "ghRuE"; <-- If I use this it works fine. # print <<EndHTML; <html><head> <meta http-equiv="Content-Type" content="text/html; charset=windows-12 +52"> <title>My Capcha</title></head> <body background="http://www.astrologybythesea.com/images/bg_coastR.jp +g"> <!-- <p><u><font size="5" color="#0000FF">My Capcha</font></u></p> --> <form action="/cgi/mycapcha.cgi" method="post"> <table border="0" width="100%"> <center> <H5>AntiBot Verifiication</H><br> <div style='height:20px;width:70px;border:1px solid blue'> <font size="2">$answer</font></div> <!-- Now get users input --> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="text" size="8" maxlength="8" name="useranswer" value="$fo +rmdata{'useranswer'}"> <input type="submit" name="verify" value="Verify"><br>&nbsp;&nbsp;&nbs +p;Type the above characters</center> EndHTML # # $UpperCaseUserAnswer is UserAnswer converted to uppercase # $UpperCaseUserAnswer = uc $formdata{'useranswer'}; # # $UpperCaseAnswer is Upper case of $anwser # ================================================= $UpperCaseAnswer = uc $answer; if ($UpperCaseUserAnswer eq $UpperCaseAnswer) { goto END; exit(0); } print <<EndHTML; </table></form></body></html> EndHTML exit(0); #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= END: print "<br>Finished Capcha; exit(0);

      You should have used <code> and </code> to delimit your code. it makes it much easier to read

      Despite that i dont think you understand the nature of how cgi works. Each time that runs because the user pressed verify it generates a new $answer, that bears no relationship to whatever was typed into $useranswer the previous time it was displayed to the user. This is what you test against the users answer so it is bound not to match this run.

      I dont do capcha stuff much, but i would include a hidden string to return in the post. This hidden string would have been used to create the previous "$answer" in a way that the end user would not be able to replicate easily. When this parameter is found in the reply you would then use it to regenerate the previous answer and compare it to what was returned in $useranwser. I might pick CGI::Session as the mechanism to store the previous answer and have the sessionid be used as the returned value to regenerate the $answer.

      Edit: add example code

      #!/usr/bin/perl use strict; use warnings; select STDOUT; $| = 1; my $session_dir='/home/huck/monks-sessions'; # must exist and be wr +iteable by www userid my $expires='+1m'; use CGI; use CGI::Session; my $session; my $cgi = CGI->new; my $tssid = $cgi->param('tssid'); my $sessiona1=undef; my $sessiona3={Directory=>$session_dir}; unless ($tssid){ new_capcha(''); } # no tssid else { $session = CGI::Session->load($sessiona1, $tssid, $sessiona3); if ( $session->is_expired ) { $session->delete(); $session->flush(); new_capcha('Try again: took too long'); } elsif ( $session->is_empty ) { $session->delete(); $session->flush(); new_capcha('Try Again:Session not found'); } else { my $oldanswer=$session->param('answer'); my $useranswer= $cgi->param('useranswer'); if (uc($oldanswer) ne uc($useranswer)) { $session->delete(); $session->flush(); new_capcha('Try Again:didnt Match'); } } } # the only way it can get here is if answer is right print $cgi->header(); print <<EndgoodHTML; <html><head> <meta http-equiv="Content-Type" content="text/html; charset=windows-12 +52"> <title>My Capcha</title></head> <body> You won </body></html> EndgoodHTML CGI::Session->find($sessiona1 ,sub {} ,$sessiona3); # clean expired +sessions exit; sub new_capcha{ my $reason=shift; $session = CGI::Session->new($sessiona1, undef,$sessiona3); my @chars = ("A".."Z", "a".."z"); my $answer; $answer .= $chars[rand @chars] for 0..4; $session->expires($expires); $session->param('answer',$answer); $session->flush(); $tssid= $session->id; print "Content-type:text/html\n\n"; print <<EndHTML; <html><head> <meta http-equiv="Content-Type" content="text/html; charset=windows-12 +52"> <title>My Capcha</title></head> <body background="http://www.astrologybythesea.com/images/bg_coastR.jp +g"> <!-- <p><u><font size="5" color="#0000FF">My Capcha</font></u></p> --> <form action="/monks-bin/capcha.pl" method="post"> <table width="100%" border="0"> <center> <h5>AntiBot Verifiication</H><br /> $reason <div> <font size="2">$answer</font></div> <!-- Now get users input --> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs +p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="text" size="8" maxlength="8" name="useranswer" value=""> <input type="hidden" name="tssid" value="$tssid"> <input type="submit" name="verify" value="Verify"><br />&nbsp;&nbsp;&n +bsp;Type the above characters </h5></center></table></form></body></html> EndHTML exit; } # newcapcha

        Then why does it WORK when I remove the '#' from '# $answer = "ghRuE"; <-- If I use this it works fine.' this line. and type in 'qhrue' then click on verify? All I asked from the beginning was why doesn't the random generate $answer work?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1190780]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-03-28 20:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found