Bash에서 문자열의 문자를 스크램블하는 방법은 무엇입니까?

Bash에서 문자열의 문자를 스크램블하는 방법은 무엇입니까?

무작위 비밀번호를 생성하지만 비밀번호를 섞어야 하는 스크립트가 있습니다. 이 작업을 수행할 방법을 찾을 수 없습니다. 도와주세요.

num=("0" "1" "2" "3" "4" "5" "7" "8" "9")
special=("@" "#" "$" "%" "*" "-" "+")
upper=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
lower=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
lower2=${#lower[*]}   #${lower[$((RANDOM%lower2))]}
upper2=${#upper[*]}   #${upper[$((RANDOM%upper2))]}
num2=${#num[*]}     #${num[$((RANDOM%num2))]}
special2=${#special[*]} #${special[$((RANDOM%special2))]}
echo "${special[$((RANDOM%special2))]}${num[$((RANDOM%num2))]}${lower[$((RANDOM%lower2))]}${upper[$((RANDOM%upper2))]}${lower[$((RANDOM%lower2))]}${upper[$((RANDOM%upper2))]}${lower[$((RANDOM%lower2))]}${upper[$((RANDOM%upper2))]}"

출력은 다음과 같습니다. @7nOyIaJ 무작위로 추출하는 방법은 무엇입니까?

답변1

"특별"이 항상 먼저 나오므로 무작위로하길 원한다고 가정합니다. 이것은 엄청난 해키 접근 방식입니다.노트:귀하의 스크립트는 입니다 scr.bash.

$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')

$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
qT*Jyv8Y

$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
QbOvX3n-

$ echo $(./scr.bash | fold -w1 | shuf | tr -d '\n')
*Q5nGgIt

이것은 조잡하지만 길을 보여줍니다.

세부 사항

fold명령은 출력을 한 줄에 1자로 분할합니다. 다른 방법도 있겠지만 저는 이걸 선택했습니다 fold. 이 shuf명령은 행을 무작위 순서로 "섞습니다". 이 명령은 우리가 만든 초기 접기에서 tr줄바꿈()을 제거 합니다.\n

답변2

@slm이 제공한 답변은 셸에서 사용할 수 있는 도구를 잘 활용하지만 "scr.bash"와 결합하면 약간 복잡해집니다. Python(버전 2.7 또는 3.x)을 사용하는 경우 동일한 작업을 더 쉽게 수행하는 스크립트는 다음과 같습니다.

#!/usr/bin/env python
"""
Create a formulaic but reasonably strong password.
"""

import random

def shuffled_password():
    """Using one random member of special and num and three members each
       from upper and lower return a shuffled string of their concatenation.
    """
    num = list('012345789')
    special = list('@#$%*-+')
    upper = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
    lower = list('abcdefghijklmnopqrstuvwxyz')
    random.shuffle(num)
    random.shuffle(special)
    random.shuffle(upper)
    random.shuffle(lower)

    letters = [special[0], num[0]]
    letters.extend(lower[0:3] + upper[0:3])
    random.shuffle(letters)
    s = ''.join(letters)  # funny way to turn list of chars into string
    return s

if __name__ == '__main__':
    print(shuffled_password())

나는 당신의 접근 방식의 조합적 복잡성을 탐구하는 과정에서 이 코드를 작성했습니다. 위에서 누군가 pwgen;를 사용한다고 언급했는데 처음에는 집에서 만든 방법보다 더 강력할 것이라고 생각했지만 내 추측은 틀렸습니다.

그렇지 않더라도 귀하의 방법으로 shuffle(letters)210억 개의 조합이 생성될 것입니다. 이것은엔트로피 추정39비트. 다음은 강도 테스트의 비공식 등급입니다.

36 - 59비트 = 합리적으로 안전한 네트워크 및 회사 비밀번호

최종 셔플을 추가하면 믹스에 약 5비트의 엔트로피가 추가됩니다. 참고로,

pwgen --symbols --numerals

추정 엔트로피가 37비트인 비밀번호를 생성합니다. 나는 이것이 "기억할 수 있는" 비밀번호를 생성하려고 시도하는 pwgen의 결과라고 생각합니다. 이는 어떻게든 출력 세트를 줄입니다. 이는 강도 테스트의 범주에 따라 여전히 "합리적"입니다.

참고: 특히 여러 순열의 조합 수학은 제한되어 있으며 수정을 환영합니다.

답변3

이것퓨어 배쉬솔루션도멀티바이트 UTF-8 문자와 함께 작동, 로캘이 올바르게 설정된 경우(예 LANG=C.UTF-8: )

우리는 단순히 문자열 조작과 일부를 사용합니다.강타 친화적다음과 같은 알고리즘피셔-예이츠 셔플:

# shuffle() - shuffle  a string
# $1: The string to shuffle
#
# The string is shuffled using the Fisher–Yates shuffle method :
# https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
#
# @return: 0,  output the shuffled string to stdout.
shuffle() {
    local _str="$1" _res
    local -i _i _cur

    for (( _i = ${#_str} ; _i > 0; --_i )); do
        _cur=$((SRANDOM % _i))
        _res+=${_str:$_cur:1}
        _str="${_str:0:_cur}${_str:_cur+1}"
    done
    printf "%s" "$_res"
}

결과:

$ for i in {1..5}; do echo $(shuffle "@7nOyIaJ"); done
@IJn7Oay
Oa7Jn@yI
Oa@n7IJy
JaO7ny@I
OJI@n7ay
$ for i in {1..5}; do printf "%s\n" $(shuffle "abc山藤123Å"); done
2bca13藤Å山
Åc13藤a山2b
a2b山1c3Å藤
1a3b藤2cÅ山
山3Åc1a2藤b

답변4

나는 가장 간단한 방법이 (원천):

echo "

관련 정보