【Ruby】暗号生成(password generator)プログラムを作ってみた

# 初めに
あるサイトで新規会員登録をしようとすると「強力な暗号？」みたいなのが出てきて、クリックすると長いパスワードが自動生成されたという経験があります。それと似たような内容を学習したので、rubyでプログラムを作ってみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

# 結果物
文字（アルファベット）と記号、数字の数を順番に入力すると入力した合計分の強力なパスワードが生成される。

# 作業手順
①やりたいことをまず文章で書く（アルゴリズム）
②細かな問題の記述
③文章を元にフローチャートを書く
④プログラムを書く

#大きな流れ
- アルファベットを用意する
- 記号を用意する
- 数字を用意する
- 結果を表示させる
- もう一度やり直すかプログラムを終了するか選ばせる

# 細かな作業&ロジック
- ランダムに生成された文字列、数字、記号をくっ付けた結果は文字列、数字、記号の順になっているため、ランダムに混ぜてあげる必要がある
- 上記の結果物をランダムに混ぜるには配列にする必要がある
- 配列にした上でshuffle関数を使ってランダムにする
- 配列になっている結果物は文字列に戻す（join関数を使う）

# フローチャート
![スクリーンショット 2021-04-25 9.28.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/6e56c94c-5002-a131-ce63-48e6f653ea1b.png)


# 暗号を生成する関数を作成
文字列と数字、記号が入っている配列を用意します。ユーザーから入力してもらった引数（文字の数、数字の数、記号の数）を利用し、文字列と数字、記号を引数の分だけくっ付けます。くっ付けた結果を配列に入れ直し、ランダムに混ぜたあと文字列に戻します。

```ruby
#アルファベット（大、小）と数字（0~9)、記号を配列で用意する
LETTERS = ("a".."z").to_a + ("A".."Z").to_a
NUMBERS = ("0".."9").to_a
SYMBOLS = ['!', '#', '$', '%', '&', '(', ')', '*', '+', '~', '¥', '[', ']', '?', '<', '>', '/', '@']
```

```ruby
#暗号を生成する関数を定義
def cipher(number_of_letters, number_of_numbers, number_of_symbols)
  output = ""    #出力結果を保存する入れ物を用意
  number_of_letters.times do       #入力された文字の数だけ、LETTERSから取り出してくっ付ける
    random_letter = LETTERS[rand(LETTERS.length)]
    output << random_letter
  end
  number_of_numbers.times do        #入力された数字の数だけ、NUMBERSから取り出してくっ付ける
    random_number = NUMBERS[rand(NUMBERS.length)]
    output << random_number
  end
  number_of_symbols.times do       #入力された記号の数だけ、SYMBOLSから取り出してくっ付ける
    random_symbol = SYMBOLS[rand(SYMBOLS.length)]
    output << random_symbol
  end

  #くっ付けた暗号文は文字列、数字、記号順になっているため、それをランダムに混ぜる処理
  array_output = []    #ランダムにした結果の入れ物を用意
  array_output = output.chars    #String型になっているoutputを配列に変換

  array_of_cipher_text = array_output.shuffle        #array_outputを混ぜる（並び順をランダムにする）
  cipher_text = array_of_cipher_text.join         #配列のarray_of_cipher_textをsrtingにする
  return cipher_text             #完成物（cipher_text)をreturn
end
```

# メインの処理を記述
loop文を使って「いいえ」を入力するまで繰り返し実行されるようにします。

```ruby
#メインの処理
loop do
  #それぞれ文字数、記号の数、数字の数を入力してもらう
  puts "パスワードに使うアルファベットの文字数を教えてください。"
  input_number_of_letters = gets.to_i
  puts "記号の数を教えてください。"
  input_number_of_symbols = gets.to_i
  puts "数字の数を教えてください。"
  input_number_of_numbers = gets.to_i

  #結果の出力
  returned_cipher_text = cipher(input_number_of_letters, input_number_of_symbols, input_number_of_numbers)  #cipher関数の実行
  puts "生成された暗号文は「#{returned_cipher_text}」です。"

  #もう一度やり直すかプログラムを抜けるかを選択してもらう
  puts "もう一度やりますか？「はい」か「いいえ」を入力してください。"
  restart = gets.chomp
  if restart == "いいえ"            #いいえを入力した場合はさようならが出力され、プログラムを終了
    puts "さようなら"
    break
  end
end

```

実行結果は以下の通り

```cl
❯ ruby password_generator.rb
パスワードに使うアルファベットの文字数を教えてください。
10
記号の数を教えてください。
5
数字の数を教えてください。
8
生成された暗号文は「*&%Rt9w!>C[4c8&f9lt>s6b」です。
もう一度やりますか？「はい」か「いいえ」を入力してください。
いいえ
さようなら
```

#参考記事
https://docs.ruby-lang.org/ja/3.0.0/method/String/i/chars.html
https://docs.ruby-lang.org/ja/3.0.0/method/Enumerable/i/entries.html
https://docs.ruby-lang.org/ja/3.0.0/method/Range/i/each.html
http://pikawaka.com/ruby/rand
https://docs.ruby-lang.org/ja/latest/method/Array/i/shuffle.html