Random String Generator Using shuf Utility

用 shuf 產生隨機字串的 BASH 程式

【摘要】介紹用 Linux 核心程式中的 shuf 產生隨機字串的方法。字元可以只是數字、小寫英文字母、大寫英文字母、符號,或這四類的任意組合。字串長度不限。


【前言】

一、有非常多的方法可以產生隨機字串,例如下行指令可以產生 16 個字元的隨機字串:

tr -cd '[:graph:]' < /dev/urandom | head -c 16 ; echo

本文敘述另一種方法,可以依需求選擇字元種類,而長度隨意。字元可以是單純的數字、小寫字母、大寫字母,或各種組合,也可加入符號,共有十四種類別。隨機字串的產生主要是靠 shuf 指令。


二、本文曾在 Google 的 Blogger 發表過,近日再次檢查更新,分享於此。


三、使用方法:

請將【指令檔】內容存成 random.sh 檔,然後在虛擬終端機執行 bash random.sh


【指令檔】

 #!/bin/bash
 # 產生隨機字串,可選擇種類,且長度不限
 
 # 定義各類基本字串
DIGIT='0123456789'
LOWER='abcdefghijklmnopqrstuvwxyz'
UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
SYMBOL='<>()[]{}+-=:;,.?!~@#$%^&|'
 # 符號不含 _ 和 *,因為會有問題
 
 # 詢問字串種類
clear
echo "類別:"
echo
echo "a)數字,如:0438820716571245686094639413018323929575045781"
echo "b)小寫字母,如:usfomftarmavvwqywopizpbhcdejnnqukxtlbeyhis"
echo "c)大寫字母,如:IUEFZVBDWISGUDRNLGHPKMAEJXRVFSPLXMZTWJBYYO"
echo "d)大小寫字母,如:bGEXiFxdutBkvZCnRLVqlTszaUgoWAMYwmhcrfej"
echo "e)數字 + 小寫字母,如:q07d14n182y5f23zmb43ri67e5gv98cl6jo"
echo "f)數字 + 大寫字母,如:64O42E6PA5K2091D1CG2Z010L6RY33QBU3T"
echo "g)數字 + 大小寫字母,如:Na2b17utm64E5QxzjsLXPiRd9rBfhp18M"
echo "h)數字 + 符號,如:+674{9<!34)236;4531]-8@7[5}$85(980#~2^9"
echo "i)小寫字母 + 符號,如:fb{rvd)itu$-q.,[;z<pgsh~^o#@la!e}]y"
echo "j)大寫字母 + 符號,如:-K;@^Z<L]?C>TPH(M+.&:UJN=B)}S$X%QIO"
echo "k)大小寫字母 + 符號,如:|%J:N]&{x;.!q,MpeLfni}Ia+jlQPyVOu"
echo "l)數字 + 小寫字母 + 符號,如:6]d^&7yu@h7jwar40(o,k18iel29"
echo "m)數字 + 大寫字母 + 符號,如:0~G7EU27T}3LZ5I1>1K23W,6J]7-"
echo "n)數字 + 大小寫字母 + 符號,如:}>2,$S[hxCRGyE6i%4V0Yu;Ipz"
echo
read -n 1 -p "請選擇類別(用 a~n 小寫字母,餘鍵中止程式): " TYPE
echo
 
 # 檢查輸入是否適合,若否,中止程式;若合,詢問字串長度
if [ $(expr match ${TYPE} [a-n]) -eq 0 ]
then
  echo "輸入不適合,中止程式!"
  exit
else
  while [[ $? -ne 0 ]]
  do
    clear
    read -p "欲產生的字串長度(正整數): " NUM
    [[ ${NUM} -gt 0 ]] 2>/dev/null
    # 檢查輸入是否為正整數,若否,重問
  done
fi
 
 # 主要指令段
function code {
  REPEAT=$(( ${NUM} / $(expr length ${1}) ))
  # 計算需要重複的次數;${1} 是該類別的基本字串
  for (( i=${REPEAT}; i>=0; i-- ))
  # 加長字串直到不小於所需長度
  do
    CODES+=${1}
  done
  CODES=$(shuf -z -e `echo ${CODES} | sed -r 's/\B/ /g'`)
  # 先將字串的每個字元分開,亂排,再合併成一個字串
  echo ${CODES:0:${NUM}}
  # 從頭輸出所需長度
} 2>/dev/null
 
case "${TYPE}" in
 # 後面的引數是基本字串
 # 數字只有十個,為了和其他類別有相似的出現機率,故共三次,且盡量不連續
  a) code ${DIGIT};;
  b) code ${LOWER};;
  c) code ${UPPER};;
  d) code ${LOWER}${UPPER};;
  e) code ${DIGIT}${DIGIT}${LOWER}${DIGIT};;
  f) code ${DIGIT}${UPPER}${DIGIT}${DIGIT};;
  g) code ${DIGIT}${LOWER}${DIGIT}${UPPER}${DIGIT};;
  h) code ${DIGIT}${DIGIT}${SYMBOL}${DIGIT};;
  i) code ${LOWER}${SYMBOL};;
  j) code ${UPPER}${SYMBOL};;
  k) code ${LOWER}${UPPER}${SYMBOL};;
  l) code ${DIGIT}${LOWER}${DIGIT}${SYMBOL}${DIGIT};;
  m) code ${DIGIT}${UPPER}${DIGIT}${SYMBOL}${DIGIT};;
  n) code ${LOWER}${DIGIT}${UPPER}${DIGIT}${SYMBOL}${DIGIT};;
  *) exit;;
esac
 
exit

發表留言