質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Q&A

解決済

3回答

2232閲覧

ランダムパスワード(英数字混合)を生成したい

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

0グッド

0クリップ

投稿2020/11/16 08:00

railsでアプリケーションを作成しており、テストユーザーログイン機能の実装を行っています。
パスワードをランダムで生成したいのですがうまくいかずにいるため助けていただきたいです。

開発環境

Ruby 2.6.5
Rails 6.0.3.3

現状のコード

controller

1class Users::SessionsController < Devise::SessionsController 2 def new_guest 3 user = User.find_or_create_by!(nickname: 'ゲストユーザー', email: 'user@example.com') do |user| 4 user.password = SecureRandom.alphanumeric 5 end 6 sign_in user 7 redirect_to root_path, notice: 'ゲストユーザーとしてログインしました。' 8 end 9end

モデルには以下のバリデーションを設定しています

PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i.freeze validates_format_of :password, with: PASSWORD_REGEX, on: :create, message: 'には半角英字と半角数字の両方を含めて設定してください'

英数字混合のバリデーションを指定しているためSecureRandom.alphanumericではエラーが生じることがあります。
そのため他の方法を調べたところSecureRandom.hexを使うといいのではないかと思ったのですがhex文字列についてもよく理解できていません。

そこで以下2点について教えていただきたいです。

1.SecureRandom.hex(引数は指定せず32桁のパスワードを生成する)にした場合英数字混合の文字列が必ず生成されるのでしょうか?
2.SecureRandom以外にランダムパスワード(英数字混合)を生成する方法があれば教えていただきたいです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

mkpasswdやpwgenを使うのはどうでしょうか?(OSにインストールされてなきゃ使えません)

以下、rubyを使った事が無く今インストールして試しただけなので推奨されないやり方の可能性もあります

ubuntu

1require 'open3' 2stdin, stdout, stderr, wait_thr = Open3.popen3('pwgen -s 32 -n 1 -c 1 1') 3pw = stdout.gets(nil)

centos

1#未確認 2require 'open3' 3stdin, stdout, stderr, wait_thr = Open3.popen3('mkpasswd -l 32 -c 1 -C 1 -d 1 -s 0') 4pw = stdout.gets(nil)

ubuntuの方は動作確認しましたが、もうruby消したので質問には答えられません。

追記

似たようなオプション持ってるライブラリがあるようなので紹介のみ。
https://www.rubydoc.info/gems/pwgen/1.0.2
※前述の通りruby削除済みなので確認はしてません

投稿2020/11/16 08:57

編集2020/11/16 09:27
hentaiman

総合スコア6421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/11/16 11:38

ありがとうございます。 mkpasswdやpwgenに関しては全くの無知の状態ですのでご提示いただいたライブラリ含め、勉強してみます。
guest

0

ベストアンサー

力技ですが、仮に32文字のパスワードを生成する場合です。
30文字をSecureRandom.alphanumericで生成します。(かつ小文字に変換)
残りの2桁にランダムなアルファベット1文字と数字1文字を付け加えます。
最悪でも1文字はアルファベットと数字が入ります。
もっと数字もしくはアルファベットの桁数を増やしたい場合は、適当に桁数を調整してください。
アルファベット2文字、数字3文字にしたいなら
addw = ['a'..'z'].sample(2).join + ['0'..'9'].sample(3).join
のようにします。SecureRandom.alphanumericの桁数はその分小さくしてください。

ruby

1require 'securerandom' 2#小文字のパスワード 3pass = SecureRandom.alphanumeric(30).downcase 4#念のためランダムなアルファベット1文字と数字1文字を付加する 5addw = [*'a'..'z'].sample(1).join + [*'0'..'9'].sample(1).join 6pw = pass + addw 7 8p pass 9p addw 10p pw 11#最後が必ず数字になる為シャッフルする 12pw = pw.scan(/./).shuffle.join 13p pw 14 15

実行結果
"8c4xnagoqc6mqzsk01e2y6jbrho0lp"
"u3"
"8c4xnagoqc6mqzsk01e2y6jbrho0lpu3"
"lbz46uch8ro06g3oykqpe2nq1cs0jmxa"

投稿2020/11/16 08:54

編集2020/11/16 11:15
tatsu99

総合スコア5438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/11/16 11:40

なるほど。 そのようなやり方もあるのですね。 参考にさせていただきます。 ありがとうございました。
guest

0

SecureRandom.hex(引数は指定せず32桁のパスワードを生成する)にした場合英数字混合の文字列が必ず生成されるのでしょうか?

必ずそうなる保証はありません。完全にランダムであれば「数字ばかり」や「英字ばかり」の出る確率がないと逆におかしいです。

SecureRandom以外にランダムパスワード(英数字混合)を生成する方法があれば教えていただきたいです。

ランダム性を落とす方法を除外するなら「条件を満たすまでSecureRandomを引き続ける」のがいちばんやりやすいかと思います。

投稿2020/11/16 08:23

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/11/16 08:26

SecureRandom.alphanumeric(16文字)がアルファベットだけ/数字だけになる確率は3.8%程度です。引き直しが延々続く確率はごくわずかです。
maisumakun

2020/11/16 08:59 編集

本題ではありませんが、記号を設定できないバリデーションはよろしくないかと思います。
退会済みユーザー

退会済みユーザー

2020/11/16 11:41

やはり100%ということはないのですね。 ありがとうございます。 ご指摘いただいたバリデーションに関しても1度考え直します。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問