как проверить наличие специальных символов в генераторе паролей bash - PullRequest
1 голос
/ 09 июля 2011

Предполагается, что это простой bash-скрипт, но превращается в монстра. Это 5-я попытка. Вы даже не хотите видеть чудовище из 30 строк, которое было попыткой № 4 ..:)

Вот что я хочу сделать: Скрипт генерирует случайный пароль с $ 1 = длина пароля и $ 2 = количество специальных символов, присутствующих в выходных данных.

Или, по крайней мере, перед отправкой в ​​стандартное заверение убедитесь, что существует хотя бы 1 специальный символ. Я бы предпочел первое, но соглашусь на второе.

Вот моя очень простая 5-я версия этого скрипта. У него нет подтверждения, или $ 2:

#!/bin/bash
cat /dev/urandom | tr -dc [=!=][=@=][=#=][=$=][=%=][=^=][:alnum:] | head -c $1

Это прекрасно работает, и это достаточно безопасный пароль с использованием:

$ passgen 12
2ZuQacN9M@6!

Но это, конечно, не всегда печатает специальные символы, и теперь для меня стало навязчивой идеей разрешить выбирать, сколько специальных символов присутствует в выходных данных. Это не так просто, как я думал.

Имеет смысл?

Кстати, я не возражаю против полной переделки кода, мне было бы очень интересно увидеть некоторые креативные решения!

(Кстати: я пытался передать его в egrep / grep различными способами, но безрезультатно, но у меня есть ощущение, что это возможное решение ...)

Спасибо Kevin

Ответы [ 5 ]

0 голосов
/ 11 июля 2011

Вы можете посчитать количество специальных символов, используя что-то вроде:

number of characters - number of non special characters

Попробуйте:

$ # define a string
$ string='abc!d$'                    
$ # extract non special chars to letters
$ letters=$(echo $string | tr -dc [:alnum:] )  
$ # substract the number on non special chars from total
$ echo $(( ${#string} - ${#letters} ))         
2

Последняя часть $(( ... )) вычисляет математическое выражение.

0 голосов
/ 09 июля 2011

Вы также можете использовать класс символов в раскрытии параметров, чтобы удалить все специальные символы в строке, а затем применить некоторую простую математическую функцию длины строки Bash, чтобы проверить, было ли минимальное (или точное) количество специальных символов в пароле.

# example: delete all punctuation characters in string
str='a!@%3"'
echo "${str//[[:punct:]]/}"   

# ... taking Cfreak's approach we could write ...
(
set -- 12 3
strlen1=$1
strlen2=0
nchars=$2
special_chars='[=!=][=@=][=#=][=$=][=%=][=^=]'  

HASRANDOM=0
while [ $HASRANDOM -eq 0 ]; do
  PASS=`cat /dev/urandom | LC_ALL=C tr -dc "${special_chars}[:alnum:]" | head -c $1`
  PASS2="${PASS//[${special_chars}]/}"
  strlen2=${#PASS2}
  #if [[ $((strlen1 - strlen2)) -eq $nchars ]]; then   # set exact number of special chars
  if [[ $((strlen1 - strlen2)) -ge $nchars ]]; then   # set minimum number of special chars
    echo "$PASS"
    HASRANDOM=1
  fi
done
)
0 голосов
/ 09 июля 2011

Как насчет этого:

HASRANDOM=0
while [ $HASRANDOM -eq 0 ]; do
    PASS=`cat /dev/urandom | tr -dc [=!=][=@=][=#=][=$=][=%=][=^=][:alnum:] | head -c $1`
    if [[ "$PASS" =~ "[~\!@\#\$%^&\*\(\)\-\+\{\}\\\/=]{$2,}" ]]; then
        HASRANDOM=1
    fi  
done

echo $PASS

Поддерживает указание символов в выводе. Вы можете добавить символы в регулярное выражение, хотя я не могу заставить работать квадратные скобки, даже если их убрать.

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

0 голосов
/ 09 июля 2011

Сохраняйте это простым ... Решение в awk, которое возвращает количество "специальных символов" на входе

BEGIN {
    FS=""
    split("!@#$%^",special,"")
}
{
    split($0,array,"")
}
END {
    for (i in array) {
        for (s in special) {
            if (special[s] == array[i])
                tot=tot+1
        }
    }
    print tot
}

Пример вывода для a2ZuQacN9M@6! равен

2

Аналогичный подход в bash:

#!/bin/bash
MyString=a2ZuQacN9M@6!
special=!@#$%^

i=0
while (( i++ < ${#MyString} ))
do
   char=$(expr substr "$MyString" $i 1)
   n=0
    while (( n++ < ${#special} ))
    do
       s=$(expr substr "$special" $n 1)
       if [[ $s == $char ]]
       then
           echo $s
       fi
    done
done
0 голосов
/ 09 июля 2011

Проверка специальных символов проста:

echo "$pass" | grep -q '[^a-zA-Z0-9]'

Примерно так:

while [ 1 ]; do
    pass=`cat /dev/urandom | tr -dc [=!=][=@=][=#=][=$=][=%=][=^=][:alnum:] | head -c $1`
    if echo "$pass" | grep -q '[^a-zA-Z0-9]'; then
        break;
    fi
done

И, наконец,

normal=$(($1 - $2))
(
for ((i=1; i <= $normal; i++)); do
    cat /dev/urandom | tr -dc [:alnum:] | head -c 1
    echo
done
for ((i=1; i <= $2; i++)); do
    cat /dev/urandom | tr -dc [=!=][=@=][=#=][=$=][=%=][=^=] | head -c 1
    echo
done
) | shuf | sed -e :a -e '$!N;s/\n//;ta'
...