Last active
December 17, 2015 05:39
-
-
Save bayashi/5559344 to your computer and use it in GitHub Desktop.
inspired from http://d.hatena.ne.jp/kazuhooku/20130509/1368071543
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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