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行に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 "

関連情報