Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lab_3 / lab_3

.sh
Скачиваний:
11
Добавлен:
28.01.2022
Размер:
4.18 Кб
Скачать
#!/bin/bash

# requires: bash coreutils dialog

# length of [:punct:] regex is calculated by the following command:
# cat /dev/urandom | tr -dc '[:punct:]' | fold -w 1 | head -n 100000 | sort | uniq | wc -l

# a-z: 26
# а-я: 33
# 0-9: 10
# [:punct:]: 32

DIALOG_CANCEL=1
DIALOG_ESC=255

normal_exit() {
	clear
	echo "Программа завершила свою работу"
	exit
}

err_exit() {
	clear
	echo "Программа аварийно завершила свою работу" >&2
	exit 1
}

dialog_codes() {
	case $1 in
		$DIALOG_CANCEL) normal_exit;;
		$DIALOG_ESC) err_exit;;
	esac
}

calculate_S_low() {
	values=($1)
	local S_low="${values[2]} * ${values[1]} / ${values[0]}"
	local S2_low=$(echo "${S_low}" | bc)
	S_low=$(echo "${S_low}" | bc -l)
	if [[ $(echo "${S2_low} < ${S_low}" | bc) == "1" ]]; then
		S_low=$(echo "${S2_low} + 1" | bc)
	else
		S_low="${S2_low}"
	fi

	echo "${S_low}"
}

calculate_L() {
	local S_low=$1
	local power=$2
	local L=0
	local S=0
	while [[ $(echo "${S_low} > ${S}" | bc) == "1" ]]; do
		((L++))
		S=$(echo "${power}^${L}" | bc)
	done
	
	echo "${L}"
}

gen_password() {
	local L=$1
	local regexp=$2
	local ru_set=$3
	local password=""
	if [[ "${regexp}" != "none" ]]; then
		password=$(cat /dev/urandom | tr -dc "${regexp}" | fold -w "${L}" | head -n 1)
		if [[ "${ru_set}" != "none" ]]; then
			local range=$(shuf -i 0-$((L - 1)) -n 1)
			local rand_char
			for ((i = 0; i <= range; i++)); do
				if [[ $(shuf -i 0-1 -n 1) -eq 1 ]]; then
					rand_char=$(echo "${ru_set}" | grep -Eio [а-яА-Я] | shuf -n 1)
					password=$(echo "${password}" | sed s/\./"${rand_char}"/"$((i + 1))")
				fi
			done
		fi
	else
		for ((i = 0; i < L; i++)); do
			password+=$(echo "${ru_set}" | grep -Eio [а-яА-Я] | shuf -n 1)
		done
	fi
	
	echo "${password}"
}

print_results() {
	exec 3>&1
	dialog --yes-label "Сгенерировать другой пароль" --no-label "Выход" --yesno \
		"S*:	$1\nA:		$2\nL:		$3\nПароль: $4" 0 0
	local exit_status=$?
	exec 3>&-
	dialog_codes $exit_status
	gen_alphabet $1
}

gen_alphabet() {
	local ru_set=""
	local regexp=""
	local power=0
	local L
	exec 3>&1
	local values=($(dialog --ok-label "Далее" --no-cancel --checklist "Выбор алфавита паролей" 0 0 0 \
		1 "Латинские большие" 0 \
		2 "Латинские маленькие" 0 \
		3 "Русские большие" 0 \
		4 "Русские маленькие" 0 \
		5 "Символы" 0 \
		6 "Цифры" 0 \
		2>&1 1>&3))
	local exit_status=$?
	exec 3>&-
	dialog_codes $exit_status
	for i in "${values[@]}"; do
		case $i in
			1) ((power += 26)); regexp+="A-Z";;
			2) ((power += 26)); regexp+="a-z";;
			3) ((power += 33)); ru_set+="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";;
			4) ((power += 33)); ru_set+="абвгдеёжзийклмнопрстуфхцчшщъыьэюя";;
			5) ((power += 32)); regexp+="[:punct:]";;
			6) ((power += 10)); regexp+="0-9";;
		esac
	done
	
	if [[ ${#ru_set} -eq 0 ]]; then
		ru_set="none"
	fi
	if [[ ${#regexp} -eq 0 ]]; then
		regexp="none"
	fi
	
	if [[ ${#values[@]} -eq 0 ]]; then
		gen_alphabet $1
	else
		L=$(calculate_L $1 $power)
		print_results $1 $power $L $(gen_password $L $regexp $ru_set)
	fi
}

data_input_screen() {
	exec 3>&1
	local values=($(dialog --ok-label "Далее" --no-cancel --form "Ввод исходных данных" 0 0 0 \
		"P = " 1 1 "" 1 5 40 0 \
		"V = " 2 1 "" 2 5 40 0 \
		"T = " 3 1 "" 3 5 40 0 \
		2>&1 1>&3))
	local exit_status=$?
	exec 3>&-
	dialog_codes $exit_status

	if [[ ${#values[@]} -eq 0 ]]; then
		data_input_screen
	elif [[ ${#values[@]} -lt 3 ]]; then
		exec 3>&1
		dialog --ok-label "Назад" --msgbox "Пожалуйста, заполните все поля формы" 0 0
		local exit_status=$?
		exec 3>&-
		dialog_codes $exit_status
		data_input_screen
	elif [[ ${#values[@]} -eq 3 ]]; then
		gen_alphabet $(calculate_S_low "${values[*]}")
	else
		exec 3>&1
		dialog --ok-label "Назад" --msgbox "Не используйте пробел" 0 0
		local exit_status=$?
		exec 3>&-
		dialog_codes $exit_status
		data_input_screen
	fi
}

data_input_screen
Соседние файлы в папке lab_3