Image
 
linkedin_logo.png rss_logo.jpg
twitter_logo.png youtube_logo.jpg
Latest Additions
 
EH-Net Login
Welcome Guest.






Lost Password?
No account yet? Register
Who's Online
We have 25 guests online
 
Advertisement

You are here: Home arrow Ethical Hacking Discussions and Related Certificationsarrow Programmingarrow morenames.pl
EH-Net
May 23, 2013, 07:01:35 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Go back to The Ethical Hacker Network Online Magazine Home Page
 
   Home   Help Calendar Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: morenames.pl  (Read 3234 times)
0 Members and 1 Guest are viewing this topic.
Negrita
Sr. Member
****
Offline Offline

Posts: 299



View Profile
« on: June 07, 2008, 05:51:43 PM »

I've been dilgently working my way through Laura Lemay's book Sams Teach Yourself Perl in 21 Days, and doing all the exercises at each stage. Each time I would find a bug, I would stop and not continue until I'd solved it. I've now finished chapter (day) 8 and I'm unwilling to continue, as I'm stumped by a script called morenames.pl.

This script takes its input from a list of names in a text file which I called namefile.txt. It presents you with a menu to sort the names in alpha-betical order by firstname or surname, to search for a name in the file or to exit.

The 2 sorting parts and the exit part all work fine, however it is the search part that's giving me trouble. Here is a copy of the name list I made up;

namefile.txt
Code:
Don Donzal
Chris Gates
Kirby Tucker
Ole DB
Kris Teason
Manu Zacharia
Ed Skoudis
HD Moore
Johnny Long
Oneeyed Carmen
Bill V
Role Reversal
Jim Bob
Slim Jim
Black Azarro
Gordon Lyon
Salvatore Sanfilippo
Joanna Rutkowska
Linus Torvalds
Bill Joy
Larry Wall
Dennis Ritchie
Richard Stallman

And here is a copy of the script;

morenames.pl
Code:
#!/usr/bin/perl -w
#This script reads names from a file.
#It offers a menu with which you can sort the names, or search them.

%names = ();  #hash of names
@raw = ();    #raw words
$fn = "";     #first name
$exit = 1;    #exit program
$in = '';     #temporary in
@keys = ();   #temporary keys
@n = ();      #temporary name
$search = ''; #thing to search for

while (<>) {
chomp;
@raw = split(" ", $_);
if ($#raw == 1) { #regular case
$names{$raw[1]} = $raw[0];
} else { #build a firstname
$fn = "";
for ($i = 0; $i < $#raw; $i++) {
$fn .= $raw[$i] . " ";
}
$names{$raw[$#raw]} = $fn;
}
}

while ($exit) {

print "\n1. Sort names by last name\n";
print "2. Sort names by first name\n";
print "3. Search for a name\n";
print "4. Quit\n\n";
print "Choose a number: ";

chomp ($in = <STDIN>);

if ($in eq '1') { #sort and print by last name

foreach $name (sort keys %names) {
print "$name, $names{$name}\n";
}

} elsif ($in eq '2') { #sort and print by first name

@keys = sort { $names{$a} cmp $names{$b} } keys %names;
foreach $name (@keys) {
print "$names{$name} $name\n";
}

} elsif ($in eq '3') { #find a name (1 or more)

print "Search for what? ";
chomp($search = <STDIN>);

while (@n = each %names) {
if (grep /$search/, @n) {
$keys[++$#keys] = $n[0];
}
}

if (@keys) {
print "Names matched: \n";
foreach $name (sort @keys) {
print " $names{$name} $name\n";
}
} else {
print "None found.\n";
}

@keys = (); #undefine keys for next search

} elsif ($in eq '4') { #quit
$exit = 0;
} else {
print "Not a good answer. 1 to 4 please.\n";
}
}

OK, so I run the script by typing morenames.pl namefile.txt in Linux or perl morenames.pl namefile.txt in Windows (I tested both) and choose option 3. When I get asked what to look for I type ch, but the output I get is all the names but with the names including lower case ch doubled. When I redo the test I get the correct output, but still in lower case only.

Code:
1. Sort names by last name
2. Sort names by first name
3. Search for a name
4. Quit

Choose a number: 3
Search for what? ch
Names matched:
 Black Azarro
 Jim Bob
 Oneeyed Carmen
 Ole DB
 Don Donzal
 Chris Gates
 Slim Jim
 Bill Joy
 Johnny Long
 Gordon Lyon
 HD Moore
 Role Reversal
 Dennis Ritchie
 Dennis Ritchie
 Joanna Rutkowska
 Salvatore Sanfilippo
 Ed Skoudis
 Richard Stallman
 Richard Stallman
 Kris Teason
 Linus Torvalds
 Kirby Tucker
 Bill V
 Larry Wall
 Manu Zacharia
 Manu Zacharia

1. Sort names by last name
2. Sort names by first name
3. Search for a name
4. Quit

Choose a number: 3
Search for what? ch
Names matched:
 Dennis Ritchie
 Richard Stallman
 Manu Zacharia

I would expect this second output the first time around. Note there is a line at the end of the loop @keys = (); Which is supposed to undefine keys for next search.

I would also expext to find Chris Gates in that list too. I tried using grep -i like I would in UNIX to ignore case sensitivity but Perl got very cross with me for doing this.  Embarrassed Evidently grep works differently in Perl than the way it does in UNIX. I also tried many lc and uc functions on the $name, $raw and $search variables but with no success.

So my questions are;
1. How can I change the script so that the search will be case insensitive?
2. Why does the script need 2 iterations to give me decent output?

I've searched the internet for fixes of this script and found none. I will probably find an answer to this in later chapters, but I'm stubborn and want to find this out before continuing with the info I have from the chapters until now.

BTW, I was using Perl 5.8.8 on BackTrack 2 , and ActiveState Perl 5.8.8 on Windows XP Pro if that interests anyone.
« Last Edit: June 07, 2008, 06:19:24 PM by Negrita » Logged

CEH, CCSA NG/AI, NNCSS, MCP, MCSA 2003

There are 10 kinds of people, those that understand binary, and those that don't.
shakuni
Jr. Member
**
Offline Offline

Posts: 80


View Profile
« Reply #1 on: June 08, 2008, 07:12:59 AM »

Quote
1. How can I change the script so that the search will be case insensitive?
Code:
while (@n = each %names) {
if (grep /$search/i, @n) {
$keys[++$#keys] = $n[0];
}
}
/i makes the search case-insensitive. So now you can find Chris Gates.
Quote
2. Why does the script need 2 iterations to give me decent output?
Works fine in the first iteration on my system. Thus the problem may be somewhere in you system and not in the script.
Logged

There is no rule, law or tradition that apply universally... including this one.
Negrita
Sr. Member
****
Offline Offline

Posts: 299



View Profile
« Reply #2 on: June 08, 2008, 06:21:57 PM »

Thanks shakuni, you've been more help than you realise. Firstly the /i switch works great - Chris Gates has now been found.  Tongue

Your remark about the script working fine on your system, and it beeing a problem on my system got me thinking. The thing is I had tried this on both my home PC and on my laptop from work and got the same result, before posting here.

So I got to thinking about how I had been running the script and how you had probably run it. When I ran the script I would go through the menu in numerical order to make sure all the options worked. I then thought that you had only tried option 3 in the menu. I did some testing and I found that when choosing option 3 it works fine but when choosing option 2 (Sort names by first name) before option 3 the result would be the entire list and the chosen search string doubled.

I looked at the code and found that in the loop for option 2 the array @keys is used but it is not undefined before option 3 begins. Obviously in option 3 $search is being added to @keys and this is giving the result I was getting. I managed to solve this by moving @keys = (); to the top of the loop for option 3.

The script is now working perfectly. For all those that didn't understand what I wrote above and want to know, the loop for option 3 now looks like this;

Code:
} elsif ($in eq '3') { #find a name (1 or more)

print "Search for what? ";
chomp($search = <STDIN>);

@keys = (); #undefine keys for next search

while (@n = each %names) {
if (grep /$search/i, @n) {
$keys[++$#keys] = $n[0];
}
}

if (@keys) {
print "Names matched: \n";
foreach $name (sort @keys) {
print " $names{$name} $name\n";
}
} else {
print "None found.\n";
}
Logged

CEH, CCSA NG/AI, NNCSS, MCP, MCSA 2003

There are 10 kinds of people, those that understand binary, and those that don't.
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines
Joomla Bridge by JoomlaHacks.com
Valid XHTML 1.0! Valid CSS!
Page created in 0.06 seconds with 22 queries.
 
Exclusive Deal

sansfire13_245x90_cw90.jpg
SANSFIRE 2013
June 15 - 22

5% Off w/ Code: EHN_5

SANS Deals 4 EH-Netters
5% OFF Any SANS Course in Any Format!
Coupon Code: EHN_5 Including SANS Rocky Mountain 2013 & SANS Boston 2013
Polls
Compared to this year, 2013 will be:
 
Recent Forum Topics
EH-Net News Feeds
Latest Additions
 
         
Advertisement

© 2013 The Ethical Hacker Network
Joomla! is Free Software released under the GNU/GPL License.