2009-09-23 3 views
2

Я создал небольшой скрипт генерации пароля. Мне интересно, какие улучшения могут быть сделаны для него за исключением обработки ошибок ввода, информации об использовании и т. Д. Это основная функциональность, которую я заинтересован в улучшении.Улучшите мой сценарий генерации пароля

Это то, что он делает (и что мне нравится это делать):

  1. Держи его легко изменить, которые Строчные символы (L), прописные символы (U), Число (N) и символы (S), которые используются в паролях.
  2. Я бы хотел, чтобы я нашел новый пароль для legnth 10 для меня не более двух секунд.
  3. В качестве аргумента должна использоваться переменная длина строки пароля.
  4. Должен быть принят только пароль, содержащий хотя бы один L, U, N и S.

Вот код:

#!/bin/bash 

PASSWORDLENGTH=$1 
RNDSOURCE=/dev/urandom 
L="acdefghjkmnpqrtuvwxy" 
U="ABDEFGHJLQRTY" 
N="" 
S="\-/\\)?=+.%#" 

until [ $(echo $password | grep [$L] | grep [$U] | grep [$N] | grep -c [$S]) == 1 ]; do 
    password=$(cat $RNDSOURCE | tr -cd "$L$U$N$S" | head -c $PASSWORDLENGTH) 
    echo In progress: $password # It's simply for debug purposes, ignore it 
done 
echo Final password: $password 

Мои вопросы:

  • Есть ли лучше способ проверить, если пароль является приемлемым, чем то, как я делаю это ?
  • Как насчет генерации пароля?
  • Какие-либо улучшения стиля кодирования? (Короткими именами переменных являются временные. Хотя я использую имена верхнего регистра для «константы» [я знаю, что формально нет] и строчные буквы для переменных. Вам нравится?)

Проголосовать за наиболее совершенные версия. :-)

Для меня это было просто упражнение в основном для удовольствия и как опыт обучения, хотя я начну использовать его вместо поколения из KeepassX, которое я сейчас использую. Будет интересно посмотреть, какие улучшения и предложения принесут более опытные Башистас (я сделал это слово).


Я создал небольшой базовый сценарий для измерения производительности: (В случае, если кто-то думает, что это весело)

#!/bin/bash 

SAMPLES=100 
SCALE=3 

echo -e "PL\tMax\tMin\tAvg" 
for p in $(seq 4 50); do 
    bcstr=""; max=-98765; min=98765 
    for s in $(seq 1 $SAMPLES); do 
     gt=$(\time -f %e ./genpassw.sh $p 2>&1 1>/dev/null) 
     bcstr="$gt + $bcstr" 
     max=$(echo "if($max < $gt) $gt else $max" | bc) 
     min=$(echo "if($min > $gt) $gt else $min" | bc) 
    done 
    bcstr="scale=$SCALE;($bcstr 0)/$SAMPLES" 
    avg=$(echo $bcstr | bc) 
    echo -e "$p\t$max\t$min\t$avg" 
done 
+1

Проверьте 'secpwgen' (или, может быть,' pwgen'), он уже делает это :) –

+0

Я проверю все предложения, и я ценю их! Однако у меня есть особые требования к используемым персонажам (я написал их на бумаге и удалил тех, кто слишком похож, чтобы избежать путаницы). Вопрос в большей степени связан с упражнением по кодированию, чем с его решением «любым возможным способом». Мне бы хотелось, чтобы решение Bash работало с максимально возможной зависимостью от нестандартных приложений (которые могут быть не установлены). – 2009-09-23 15:54:04

+0

Эй, какое у вас имя? ;) –

ответ

0

Вы отбрасываете пучок случайности в своем потоке ввода. Сохраните эти байты и переведите их в свой набор символов. Заменить пароль = ... заявление в цикле со следующим:

ALL="$L$U$N$S" 
password=$(tr "\000-\377" "$ALL$ALL$ALL$ALL$ALL" < $RNDSOURCE | head -c $PASSWORDLENGTH) 

повторением $ ALL является обеспечение того, есть> = 255 символов в «карте» установить.

Я также удалял безвозмездное использование кошки.

(Отредактировано, чтобы уточнить, что то, что показано выше, не предназначено для замены полного скрипта, а всего лишь внутреннего цикла.)

Edit: Вот гораздо быстрее стратегия, которая не взывать к внешним программам:

#!/bin/bash 

PASSWORDLENGTH=$1 
RNDSOURCE=/dev/urandom 
L="acdefghjkmnpqrtuvwxy" 
U="ABDEFGHJLQRTY" 
N="" 
# (Use this with tr.) 
#S='\-/\\)?=+.%#' 
# (Use this for bash.) 
S='-/\)?=+.%#' 

ALL="$L$U$N$S" 

# This function echoes a random index into it's argument. 
function rndindex() { echo $(($RANDOM % ${#1})); } 

# Make sure the password contains at least one of each class. 
password="${L:$(rndindex $L):1}${U:$(rndindex $U):1}${N:$(rndindex $N):1}${S:$(rndindex $S):1}" 

# Add random other characters to the password until it is the desired length. 
while [[ ${#password} -lt $PASSWORDLENGTH ]] 
do 
    password=$password${ALL:$(rndindex $ALL):1} 
done 

# Now shuffle it. 
chars=$password 
password="" 
while [[ ${#password} -lt $PASSWORDLENGTH ]] 
do 
    n=$(rndindex $chars) 
    ch=${chars:$n:1} 
    password="$password$ch" 
    if [[ $n == $((${#chars} - 1)) ]]; then 
     chars="${chars:0:$n}" 
    elif [[ $n == 0 ]]; then 
     chars="${chars:1}" 
    else 
     chars="${chars:0:$n}${chars:$((n+1))}" 
    fi 
done 
echo $password 

Временные тесты показывают это работает 5-20x быстрее, чем оригинальный сценарий, а время более предсказуемым от одного прохода к следующему.

+1

Хотя это * очень * вероятно, что будет представлен хотя бы один символ из каждой группы, это не гарантируется с помощью вашего метода. –

+0

Мое намерение состояло в том, чтобы просто заменить внутреннюю часть петли. Извините, что было неясно. Я считаю, что grep в предложении until гарантирует, что все классы будут представлены. – bstpierre

+0

В конце 45 и выше (не практично в реальной жизни) мой сценарий кажется быстрее вашего. Я предполагаю, что это точка безубыточности для всех вызовов внешних программ. Я нашел это немного интересным. :-) Кроме того, ваши тесты времени кажутся точными. Мне нравится, как вы не используете внешние программы. Я еще раз пойду за этим и узнаю, как ты это делаешь! Спасибо за ваш ответ! – 2009-09-25 00:56:22

0

вы могли бы просто использовать uuidgen или pwgen для генерации случайных паролей, может быть, позже перетасовки некоторых букв вокруг или что-то в этом роде

+0

Возможно, но он не использует точные символы, которые я использовал в своем собственном скрипте, который является обязательным для меня (поскольку я взял полчаса, чтобы придумать их). – 2009-09-23 15:55:49

+0

есть приложение pwgen, которое генерирует пароли случайным образом. – dsm

+0

Я тоже мог бы изучить это. Прежде всего, я ищу комментарии, если бы этот скрипт мог быть написан более элегантным или эффективным способом. Использование стороннего приложения может быть хорошей вещью, но на самом деле я считаю, что мой скрипт настолько же безопасен, как и все, что «pwgen» и т. Д. – 2009-09-23 19:19:37

0

secpwgen очень хороший (он также может генерировать более легкие для запоминания пароли diceware) - но почти исчез из сети. Мне удалось выследить копию 1.3 source & put it on github.

Это также part of Alpine Linux.

Смежные вопросы