ネットでパスワード生成出来るサービスあるじゃないですか?アレって生成結果保存してどっかに売ってたりするのかなとか思ったのでローカルでパスワードを生成することにしましたっていうだけの話。あまり精度は求めていません。
基本は前回と同じですでパターンに記号を追加しただけです。
Ascii の文字コードに関しては 8 進、10 進、16 進とありますが、ここでは 10 進を用います。0 から 127 までの間で文字として使えるのは 33 から 126 までです。
$ ascii -d
0 NUL 16 DLE 32 48 0 64 @ 80 P 96 ` 112 p
1 SOH 17 DC1 33 ! 49 1 65 A 81 Q 97 a 113 q
2 STX 18 DC2 34 " 50 2 66 B 82 R 98 b 114 r
3 ETX 19 DC3 35 # 51 3 67 C 83 S 99 c 115 s
4 EOT 20 DC4 36 $ 52 4 68 D 84 T 100 d 116 t
5 ENQ 21 NAK 37 % 53 5 69 E 85 U 101 e 117 u
6 ACK 22 SYN 38 & 54 6 70 F 86 V 102 f 118 v
7 BEL 23 ETB 39 ' 55 7 71 G 87 W 103 g 119 w
8 BS 24 CAN 40 ( 56 8 72 H 88 X 104 h 120 x
9 HT 25 EM 41 ) 57 9 73 I 89 Y 105 i 121 y
10 LF 26 SUB 42 * 58 : 74 J 90 Z 106 j 122 z
11 VT 27 ESC 43 + 59 ; 75 K 91 [ 107 k 123 {
12 FF 28 FS 44 , 60 < 76 L 92 \ 108 l 124 |
13 CR 29 GS 45 - 61 = 77 M 93 ] 109 m 125 }
14 SO 30 RS 46 . 62 > 78 N 94 ^ 110 n 126 ~
15 SI 31 US 47 / 63 ? 79 O 95 _ 111 o 127 DEL
実際に 33 から 126 までの文字を並べてみると下記のようになります。今回はこれらの文字列を使います。
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
ランダム文字列を生成する際に上記の文字列を変数として呼び出すので変数として登録しますが、この文字列を変数に格納しようと下記のようにコードを書いても正しく動きません。
str=!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
いくつか書き方がありますが、ここでは $'' 記法を使います。文字列のうち、シングルクォートのみ、バックスラッシュでエスケープしておく必要があります。
str=$'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' ^^ ^ ^
文字列ではなく、コマンドの実行結果で格納したい場合は enum や jot コマンドなどを使うのが手っ取り早いと思います。上記の文字列もこのコマンドで出力したものですがこの二つのコマンドは seq コマンドには無い、文字で出力するというオプションがあります。
(これらのコマンドのランダムオプションでも生成出来ますが遅いので今回はシェルのビルトインコマンドで行います)
enum -s "" -c START END enum -s "" -c 33 126 str=$(enum -s "" -c 33 126)
jot -s "" -c COUNT START jot -s "" -c 94 33 str=$(jot -s "" -c 94 33)
文字列を格納したら欲しい文字列長でループを回して1文字ずつ取り出します。
length=16 for ((i=0; i<length; i++)) do printf '%s' "${p:$((RANDOM%${#p})):1}" done
適当に rand という関数を作成します。
rand(){ length=$1 for ((i=0; i<length; i++)) do printf '%s' "${p:$((RANDOM%${#p})):1}" done }
何回か回してみます。
for ((i=0; i<10; i++)); do rand 16; echo; done
LIB)SyOH_RC[[QC[
X=b.'?Xw1S1_&"q~
-2#2X+aoaSWbNPAB
9_C7+v3gYSE?w~7?
kSc;]<<9+T3BgNea
x"%@0(E1[.!}2}5&
LtD|;sOa-.G#ZM+H
XCd#l9XY]/5^${YE
-8&'@%)Q//#aMKOg
9dE,qp3"`/I>uz},
同じ文字が連続しない文字列が欲しければ grep なんかで除外。
for ((i=0; i<10; i++)); do rand 16; echo; done | grep -v -E '(.)\1'
enum で生成する
LEFT .. COUNTx STEP .. RIGHT がちょっと変わった書式です。
$ i=32
$ enum -c -r -s "" 34 .. ${i}x .. 126
=%FU,r@Z4vXL~Y5";Xj[t%R9pY&7m$x,
jot で生成する
$ i=32
$ jot -c -r -s "" ${i} 33 126
iacA}9P}T3CFsqEa>:#'N{%#AhqBMtQV