Perl RAND LC / UC - PullRequest
       32

Perl RAND LC / UC

2 голосов
/ 17 января 2012

Я пытаюсь получить случайный нижний / верхний регистр в моем пароле из 42 символов.Каким-то образом я вместо этого получаю:

ucclcjuczlclucmlc0lcdlc5lc0ucdlccucmucquc5ucslc4lckucxuctlcvlcquclucpuc0ucvlczucducauczlcauc * 101 * 100 * * 100 * * * * 100 * * 100 * * 100 * *5

Ответы [ 7 ]

5 голосов
/ 17 января 2012

Нет смысла использовать lc и uc при предоставлении списка верхнего и нижнего регистра так же просто, как это:

use strict;
use warnings;

sub random_pwd {
    my $length = shift;
    my @chars = (0 .. 9, 'a' .. 'z', 'A' .. 'Z');
    return join '', @chars[ map rand @chars, 0 .. $length ];
}
print random_pwd(42);

Если вы хотите случайным образом выбрать заглавные буквы в уже существующихстрока, вот один из способов:

$str =~ s/(\w)/ rand() < 0.5 ? uc($1) : lc($1) /ge;

Несколько строже использовать [a-z] вместо \w (который также включает числа), но все, что вы теряете, это некоторая избыточная обработка (например, uc("L") или lc("2")), что не должно быть проблемой.

5 голосов
/ 17 января 2012

Проблема в том, что у вас есть строки (uc или lc), которые вы ожидаете выполнить как код, но они никогда не передаются парсеру.Вы можете передать их парсеру, используя eval EXPR, но это неправильный подход.

my @chars = ('0'..'9', 'a'..'z');
my $passwd =
   join '',
    map rand >= 0.5 ? uc : lc,
     map $chars[rand(@chars)],
      1..42;

Или еще лучше:

my @chars = ('0'..'9', 'a'..'z', 'A'..'Z');
my $passwd =
   join '',
    map $chars[rand(@chars)],
     1..42;
5 голосов
/ 17 января 2012

Почему бы просто не выбрать случайный буквенно-цифровой символ (который, в случае букв, может быть в верхнем или нижнем регистре)?

use strict;
use warnings;
my @chars=("a".."z","A".."Z",0..9);
my $password="";

foreach(1..42)
{
  #tack on a random alphanumeric character
  $password.=$chars[int(rand(@chars))] 
}

print $password . "\n";

Если вы хотите сделать lc или ucявная часть процесса, вы можете сделать что-то вроде:

use strict;
use warnings;
my @chars=("a".."z",0..9);

my $password="";

foreach(1..42)
{
  my $char=$chars[int(rand(@chars))];
  $char=uc($char) if rand() <0.5;
  $password.=$char;
}

print $password . "\n";
3 голосов
/ 17 января 2012

Ваш код объединяет строки 'lc' или 'uc' со случайными буквами, вместо того, чтобы фактически применять функции lc или uc к случайным буквам. (В любом случае, вы не можете ссылаться на встроенные функции до Perl 5.16.)

2 голосов
/ 17 января 2012

Разве это не нормально?

use Text::Capitalize;

print scramble_case "Isn't CPAN wonderful?";
1 голос
/ 18 января 2012

Уже есть несколько хороших ответов, я представлю еще два, один из которых выглядит так, как вы думали, а второй с использованием CPAN

Сначала, в порядке OP: создайте анонимные подпрограммы, которые возвращают uc или lc своего аргумента, затем случайным образом вызовите один или другой случайный символ.

#!/usr/bin/env perl

use strict;
use warnings;

my @a = (0 .. 9, 'a' .. 'z');
my @case = (sub{lc shift},sub{uc shift}); 
my $x = join '', map { $case[int rand(2)]->($a[int rand @a]) } 1 .. 42;
print "$x\n";

Хорошо, теперь вы узнали о вызове функции. Для генерации вашего пароля мы кратко рассмотрим CPAN и найдем String::Random. Это позволяет генерировать случайные строки на основе шаблонов.

#!/usr/bin/env perl

use strict;
use warnings;

use String::Random 'random_regex';

print random_regex('[a-zA-Z]{42}'), "\n";

В последний раз, когда я запускал это, я получил

LpvrMpylaaZTzmMbyBLiNQiwFZyKWWesVecvBWbLwu
0 голосов
/ 18 января 2012

Вы, вероятно, можете попробовать что-то вроде следующего одного вкладыша:

perl -le "print map { ('a'..'z', 'A'..'Z', '0'..'9')[rand 62] } 1..42"

SXQtgMmzL7hsF9EZ2p9DrGg8BudNh4QWkOQn6UurPk

perl -le "print map { ('a'..'z', 'A'..'Z', '0'..'9')[rand 62] } 1..42"

Rk6TJlBRkB3tSJ * * * * * *с ".

Источник - catonmat.net

...