Re: Optional Arguments..?
by davido (Cardinal) on Jun 03, 2012 at 03:16 UTC
|
The array, @ARGV contains the various arguments passed on the command line. To access the first element by index, it would be $ARGV[0]. You're using that first element to handle the command line switch, L, U or D. The second arg is $ARGV[1], and that's where you're passing the key. The third (optional) parameter is $ARGV[2]. That element will either have a value, or it will be undefined. To detect which, you might do something like this:
if( defined $ARGV[2] ) {
# Handle the search string.
}
else {
# Perform whatever default preparations are necessary in
# the absence of a defined search string.
}
So the key is to test $ARGV[2] for definedness. There are a couple of useful ways to do that. The most common by far is the defined built-in function. But there's also the // and //= operators, described in perlop. With //=, you could do something like this:
$ARGV[2] //= 'Default value';
In this case, if $ARGV[2] already contains a value, the line has no effect. If it doesn't contain a value, '<c>Default value' is assigned.
Using the // operator might look like this:
my $pattern = $ARGV[2] // 'Default value';
Here, $pattern receives the contents of $ARGV[2] if $ARGV[2] is defined. If it's undefined, then 'Default value' is assigned to $pattern.
The // and //= operators were introduced to Perl in version 5.10.0 (I think). So they won't work if you're stuck using older versions. defined works all the way back to the earliest Perl 5 versions, and possibly more.
Welcome to Perl! :)
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Hi Dave!
Firstly I wanna say I almost burst into happiness when you explained this.. "defined" to me. It's the one thing that my lecturer told us to google for, to implement in our codes but I just couldn't find a simple explanation to use this. Thanks a lot. Right now after using defined, my code looks like this
#!/usr/bin/perl -w
use strict;
use warnings;
use ST2614 1.0;
#subroutine guide provides user a simple documentation on how to use t
+he password manager
sub guide {
my $pwdmgr = shift;
print "usage: $pwdmgr L key [site_pattern]\n";
print "-"x5, " takes the encoding key and optional site_pattern to
+ retrieve
all saved entries that match.\n If no site_pattern, retrieve all s
+aved entries\n\n";
print "usage: $pwdmgr U key site_name login_id password [URL]\n";
print "-"x5, " Using the encoding key, add new or update existing
+entry.\n Complete set of
entry info required: Site name, login id, password, URL(Optional)\
+n\n";
print "usage: $pwdmgr D key site_name\n";
print "-"x5, " Takes in encoding key and site_name to delete entry
+; will only work if
encoding key matches and entry found matching with site_name.\n";
exit;
}
#an if-elsif loop to check which option user has selected
if ($ARGV[0] eq "L") {
sub listFunct ($;$) {
open(FILEHANDLE, "passmgr.dat") or die ("The file cannot be op
+ened!");
my $decode = ST2614::decode(FILEHANDLE, $ARGV[1]);
if ( defined $ARGV[2] ) {
for $decode (keys =~ m/$ARGV[2]/) {
print "$decode: @{ m/$ARGV[2]/ {$decode} }\n";
+
}
} else {
for $decode () {
print
}
}
}
} elsif ($ARGV[0] eq "U") {
#declare the individual variables that are to be stored
my $sitename = $ARGV[2]; #sitename will be the key in the hash of
+array
my $loginid = $ARGV[3];
my $password = $ARGV[4];
my $url = $ARGV[5];
#declare a hash of array to prepare storage of all variables to be
+ encoded together
my HoA {$sitename} = ["$loginid", "$password", "$url"];;
open(FILEHANDLE, ">>passmgr.dat") or die("The file cannot be opene
+d!");
my $encode = ST2614::encode(HoA, $ARGV[1]);
print FILEHANDLE "$encode";
close FILEHANDLE;
print "Data successfully encoded. Please remember your key.\n Your
+ key is $ARGV[1].";
} elsif ($ARGV[0] eq "D") {
} else {
guide($0);
}
What I want to achieve is to be able to print all password and related data by searching for the sitename, so for example searching for 'a' might give me yahoo and facebook, and list the passwords accordingly. Is my following code correct?
Also, I would like to be able to print all hashes of arrays in my decoded file, how do I do that?
With thanks
Junming | [reply] [Watch: Dir/Any] [d/l] |
|
It's the one thing that my lecturer told us to google for, to implement in our codes but I just couldn't find a simple explanation to use this.
Google is great, but I'm surprised your professor didn't mention the Perl documentation. It's included free of charge with every Perl distribution, and also at http://perldoc.perl.org. You can read about defined on your own terminal by typing "perldoc -f defined".
Is my following code correct?
No.
Well... your use of defined is reasonable, but besides that, NO. It doesn't compile.
Why would you post code that doesn't compile except to possibly ask why it doesn't? You can check yourself, at which point you can begin working through the error messages. For example, "Not enough arguments for keys at mytest.pl line 27, near "keys =~"" Your line numbers will probably be different, but that error message will still be there, unless the code you posted isn't what's in your editor.
There's no need for me to enumerate the error messages you're getting; Perl will do it for you when you type perl -c mytest.pl, where "mytest.pl" is the name of your script. Once you resolve the issues that perl -c tells you about, you'll run into other problems as well, such as your strange for loop around line 31. It seems to set a topical variable, but the list of items it iterates over is empty, and the print statement on the next line tries to print $_, which isn't going to contain anything meaningful.
Really, there are enough problems you probably should sit down with your instructor for a half hour and go over them together.
If you don't have it already, get yourself a copy of Learning Perl, and start reading. It will begin to flow before you know it. And remember this slightly gentler version of a famous quote within the Perl community: "You can't just make stuff up and expect the computer to know what you mean." Programming rewards attention to detail.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
Re: Optional Arguments..?
by tobyink (Canon) on Jun 03, 2012 at 08:09 UTC
|
I would strongly suggest using Getopt::Long. It takes all the headaches out of processing command-line parameters. I'd go as far as saying that if you're processing a command-line, and you want to do anything other than accept a plain old list of filenames, then you're a fool not to use it. Unless of course, that would be disallowed by the guidelines for your assignment.
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [Watch: Dir/Any] |
|
Only a guess, but I suspect at least some of the code is boilerplate supplied by the professor (the portions of the code lacking in syntax errors). Might be best to just stick to the assignment for now.
Like I said... only a guess.
| [reply] [Watch: Dir/Any] |
|
I'm fairly sure that the assignment doesn't allow for use of modules not covered in the class.
More to the point, though, so far as I'm aware, Getopt only recognizes options with a - or -- prefix. In this spec, the operation is specified with L, U, or D, not -L/-U/-D, so I don't think Getopt would even work here without changing the interface to the program.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Hi guys, thanks for the posts. I'm currently back to work on my assignment. Anyway, all of the code that is from me is written by me. My lecturer only provided a module (is it called a module?) named ST2614, which helps encode and decode my hashes. Will update if I have more questions.
Thanks a million!
UPDATE: Okay, I managed to figure out what I want to ask. The problem is this: I have to decode the encrypted file of hashes, when I manage to decode it, I declare the result to a variable. Is this correct?
Second, I want to first print only all hashes that match the argument "site name" where a user might enter 'a' and some example results are hashes with key names such as Yahoo or Facebook printed. How can I do this?
Lastly, I would like to print all hashes that are decoded. However as I declared the decoded data into a variable, I don't think I can code the program like a typical print-all-hashes that Dave provided.. There seems like something I'm supposed to do, but honestly.. I'm clueless. So I'd like to ask how I could do this as well.
For the last blank, D, it's meant to be able to delete hashes which key exactly matches the one stated by the user. I haven't started work on it, hence I left it blank.
Once again thank you guys for the help. It's the holidays in my country over here, and I have trouble contacting my lecturer. This is why I cannot contact him for questions.
| [reply] [Watch: Dir/Any] |
Re: Optional Arguments..?
by poj (Abbot) on Jun 03, 2012 at 12:45 UTC
|
Could you please show the code for the encode, decode routines.
The arguments you have in these statements don't look right to me.
my $decode = ST2614::decode(FILEHANDLE, $ARGV[1]);
my $encode = ST2614::encode(HoA, $ARGV[1]);
poj | [reply] [Watch: Dir/Any] [d/l] |
|
#/usr/bin/perl -w
# Demo Version -
# AY2012/2013 ST2614 Assignment
# PM to support Personal Password Manager
package ST2614 ;
our $VERSION = 1.0;
sub getAscii {
# This is a helper function to support encode() and decode()
#
#input a normal string
# convert each char of the string to its corresponding ascii cod
+e
# return the list of the ascii codes
# in one , delimited string
my $plaintext= shift;
my @asciilist = ();
my @tmplist = split('', $plaintext);
foreach $ch (@tmplist) {
push (@asciilist, ord($ch)); # use ord to get ascii code
}
return join(",",@asciilist);
}
sub encode {
# simple xor encoding
# Argument 1 - A string in plain text - to be encoded
# Argument 2 - A string in plain text, represent the key
# return the xor result in ascii form
my ($text , $key) = @_;
$text = getAscii($text);
$key = getAscii($key);
my @textlist = split(',',$text);
my @keyblk = split(',',$key);
my $index = 0;
my $max = @keyblk;
my @encodedlist = ();
foreach $chcode (@textlist) {
# simple xor encoding
# must use int() to force a numeric xor operation
my $secret = int($chcode) ^ int($keyblk[$index]);
push(@encodedlist,$secret); # store the result
# recycle the key block
$index = ($index+1) % $max;
}
return join(",",@encodedlist);
}
sub decode {
# simple xor decoding
# Argument 1 - encoded string in ascii list form
# Argument 2 - A string in plain text, represent the key
# return the xor result in plain text string form
my ($secret , $key) = @_;
$key = getAscii($key);
# break the line into array and xor with the keyblock
my @secretlist = split(',',$secret);
my @keyblk = split(',',$key);
my $index = 0;
my $max = @keyblk;
my $orgText = "";
foreach $chcode (@secretlist) {
my $org = int($chcode) ^ int($keyblk[$index++]);
# convert numeric ascii value back to character form
# and append it to $orgText
$orgText .= chr($org);
$index = $index % $max;
}
return $orgText;
}
1; # required to return 1 at the end of a pm file
| [reply] [Watch: Dir/Any] [d/l] |
|
OK, looks like arguments are text strings, not a filehandle or a hash ref. Can you show some lines of data from the passmgr.dat file.
poj
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|