Skip to content

Instantly share code, notes, and snippets.

@bayashi
Last active December 17, 2015 05:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bayashi/5559344 to your computer and use it in GitHub Desktop.
Save bayashi/5559344 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long qw/GetOptionsFromArray/;
use IO::Stty;
use Digest::HMAC_SHA1 qw//;
our $VERSION = 0.01;
main(\@ARGV);
sub main {
my $argv = shift;
my $config = +{};
_merge_opt($config, $argv);
_input_master_password($config);
my $digest = Digest::HMAC_SHA1->new($config->{master_password});
my $src_hash = $digest->add($config->{salt})->b64digest;
if ($config->{only_number}) {
$src_hash = _only_number($src_hash);
}
elsif ($config->{only_upper_case}) {
$src_hash = _only_case($src_hash, 'uc');
}
elsif ($config->{only_lower_case}) {
$src_hash = _only_case($src_hash, 'lc');
}
if ($config->{no_symbol}) {
$src_hash = _no_symbol($src_hash);
}
$src_hash = substr($src_hash, 0, $config->{length});
print "use this: $src_hash\n";
}
sub _no_symbol {
my $src = shift;
my $result = '';
for my $str (split '', $src) {
$str =~ s/^([^a-zA-Z0-9])$/ord($1)/e;
$result .= $str;
}
return $result;
}
sub _only_number {
my $src = shift;
my $result = '';
for my $str (split '', $src) {
$result .= ($str =~ /^\d+$/) ? $str : ord($str) % 10;
}
return $result;
}
sub _only_case {
my $src = shift;
my $case = shift || 'uc';
my $result = '';
for my $str (split '', $src) {
$result .= $case eq 'uc' ? uc $str : lc $str;
}
return $result;
}
sub _input_master_password {
my $config = shift;
my($input, $input_again);
local $SIG{INT} = sub { _stty('echo'); exit; };
_stty('-echo');
_INPUT:
print "Input master password:\n";
$input = <STDIN>;
chomp($input);
print "Again, input same master password:\n";
$input_again = <STDIN>;
chomp($input_again);
if ($input ne $input_again) {
print "[Err] Your passwords are NOT same. Try to input again.\n\n";
$input = $input_again = '';
goto _INPUT;
}
_stty('echo');
$config->{master_password} = $input;
}
sub _stty {
my $echo = shift;
IO::Stty::stty(\*STDIN, $echo || 'echo');
}
sub _merge_opt {
my ($config, $argv) = @_;
Getopt::Long::Configure('bundling');
GetOptionsFromArray(
$argv,
's|salt=s' => \$config->{salt},
'l|length=i' => \$config->{length},
'only-number' => \$config->{only_number},
'only-uc' => \$config->{only_uc},
'only-lc' => \$config->{only_lc},
'no-symbol' => \$config->{no_symbol},
'h|help' => sub {
_show_usage(1);
},
'v|version' => sub {
print "$0 $VERSION\n";
exit 1;
},
) or _show_usage(2);
$config->{length} ||= 8;
$config->{digest} ||= 'sha1';
}
sub _show_usage {
my $exitval = shift;
require Pod::Usage;
Pod::Usage::pod2usage($exitval);
}
__END__
=head1 NAME
gen_password.pl - generate your password
=head1 SYNOPSIS
$ gen_password.pl [options]
=head2 OPTIONS
-s, --salt a string digits for generating password
-l, --length password length(default: 8)
--only_number used only number string
--only_uc used only upper case
--only_lc used only lower case
--no_symbol switch a symbol to number
-h, --help show this help
-v, --version show the version
=head2 EXAMPLE
$ ./gen_password.pl -s example.com -l 8
Input master password:
Again, input same master password:
use this: 6X+LRMiF
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment