PHP

openssl_random_pseudo_bytesでランダムな文字列を作りたい

実装方法

substr(base64_encode(openssl_random_pseudo_bytes(32)),0,8)

でたとえばa5+1SQOdみたいな文字列が生まれる。

疑問

openssl_random_pseudo_bytesで何ビット生成するべきなのか?

上記の例だと32ビット生成され、base64_encodeをすることで44文字の文字列が生成される。
つまり44文字以上のランダムな文字列は作れない。(正確には末尾に1文字=が確定で入るので43文字)

そもそもbase64ってどうやるんだっけ

Wikipedia先生によると
1. 32ビットのビット列(?)が来たときに
1000 1111 1101 1111 1011 1001 1011 1010 (4*8)
2. 6ビットずつにして
100011 111101 111110 111001 101110 10
3. 足りないところを0で埋めて
100011 111101 111110 111001 101110 100000
4. 文字にする
j 9 + 5 u g
5. 4の倍数文字になるまで=を入れる
j9+5ug==

あれ…?8文字しか生成されないぞ…?

なぜ44文字も生成されるのか

ヒント1
32*1.3333 = 42.56
ヒント2

Base64 でエンコードされたデータは、エンコード前のデータにくらべて 33% 余計に容量が必要です。
PHPマニュアル

たぶん生成された0、1の文字列base64でエンコードしている。
乱数生成器で生成されたものを単純に文字列にしてるだけなので安全性には問題はないはず

結論

floor(欲しい文字数 / 1.3333)ぐらいのビット数は最低限生成すべきだと思う(適当)
安全側に振るならceilの方が良いかも
暗号よくわかんないや(放棄)