クリエイティブな毎日を“楽しむ”

perl,php,rubyでランダムな文字列を生成する方法

たむさん
WEB

パスワードとかに使えそうなランダムな文字列を生成する方法をとりあえずよく使う perl, php, ruby の3つの言語で書いてみました。
使う文字種はアルファベットの小文字、大文字、数字、各種記号を含みます。

流れとしては

  1. 上記の文字を含む配列を作って
  2. 配列内からランダムな1文字を取得して連結していき
  3. 指定された文字長になったらその文字列を返す

というものです。

それではそれぞれの言語でのコードです。

perl

#!/usr/bin/perl

use strict;

sub generate_password {
    my $length = shift @_ || 8;

    my @seed = (
        'a'..'z',
        'A'..'Z',
        0..9,
        '!', '"', '#', '$', '%', '&', "'", '(', ')', '=', '~',
        '|', '-', '^', '@', '`', '+', '*', '<', '>', '_'
    );
    my $str = '';
    while(length $str < $length) {
        $str .= @seed[int rand(scalar @seed)];
    }

    return $str;
}

print generate_password . "\n";

php

<?php

function generate_password($length = 8)
{
    $salt = array_merge(
        range('a', 'z'),
        range('A', 'Z'),
        range(0, 9),
        array('!', '"', '#', '$', '%', '&', "'", '(', ')', '=', '~'),
        array('|', '-', '^', '@', '`', '+', '*', '<', '>', '_')
    );

    $str = '';
    while(strlen($str) < $length) {
        $str .= $salt[mt_rand(0, count($salt) - 1)];
    }

    return $str;
}

echo generate_password() . PHP_EOL;

ruby

#!/usr/local/bin/ruby

def generate_password(length = 8)
  symbols = [
    '!', '"', '#', '$', '%', '&', "'", '(', ')', '=', '~',
    '|', '-', '^', '@', '`', '+', '*', '<', '>', '_'
  ]
  seed = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a + symbols
  str = ''

  while (str.length < length)
    str += seed[rand(seed.length)].to_s
  end

  str
end

p generate_password

ruby の場合は0-9の配列を作成するときに数字としての配列を作成していると、
文字を連結するときに .to_s メソッドで文字列として連結してやらないと文字列に数字を足そうとして次のようなエラーが起こることがあります。

`+’: can’t convert Fixnum into String (TypeError)

回避方法は上記のように結合時に .to_s を使うか、(0..9).to_a を (‘0’..’9′).to_a として文字の配列にしておくかです。
それぞれのやり方で配列を生成したのを比べるとわかると思います。

p (0..9).to_a      # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
p ('0'..'9').to_a  # => ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

終わりに

いかがでしょうか。
パスワードを生成したいときにサクッと実行したらかんたんにランダムパスワードが作成できますよ。

蛇足

各言語別にランダム関数の挙動が異なります。
指定された最大値を含む値を返す => php
指定された最大値を含まない値を返す => perl, ruby
php の場合は mt_rand(0, 10) とすると 0以上10以下(10を含む) の数値を返しますが、
perl, ruby の rand(10) だと 0以上10未満(10を含まない) の数値を返します。

たむさん