perlで.htpasswdを生成する

159人分の基本認証を作ってくれという依頼。htpasswdコマンドを159回起動して、318回パスワードを間違いなくタイプできれば魔法使いになれるらしいが、あいにくそんな技量は持ち合わせていないのでちょっとしたスクリプトを作成。
htpasswdはUNIXパスワードと同じくcrypt()関数でパスワードを暗号化しています。平文のパスワードとランダムの種を与えてあげればいいので、パスワードを作成する関数はこんな感じ。種の元になる文字列は適当でいいんだけど、ウェブ上の例をみるとみんなこんな風にa-zから順序良く並べているので、その例に習いました。

sub mkpasswd {
        my($pass_plain)=@_;
        my(@salt_set)=('a'..'z','A'..'Z','0'..'9','.','/');
        srand(time|$$);
        my($seed1) = int(rand(64));
        my($seed2) = int(rand(64));
        my($salt) = $salt_set[$seed1] . $salt_set[$seed2];
        return crypt($pass_plain,$salt);
}

今回の場合は元になるデータがCSVでこんな風に与えられていたので

user1:password1
user2:password2

スクリプト全文はこんな感じ。

#!/usr/bin/perl

while(<>){
  chop ;
    ($user,$passwd_plain) = split(/,/);
    $enc_pass = &mk_passwd($passwd_plain);
    print $user,":",$enc_pass,"\n" ;
}
sub mk_passwd {
        my($pass_plain)=@_;
        my(@salt_set)=('a'..'z','A'..'Z','0'..'9','.','/');
        srand(time|$$);
        my($seed1) = int(rand(64));
        my($seed2) = int(rand(64));
        my($salt) = $salt_set[$seed1] . $salt_set[$seed2];
        return crypt($pass_plain,$salt);
}

ところで、実際にはちょいちょいとスクリプトを書いてパスワードファイルを変更したんですが、なぜかパスワードが通らない現象。うだうだと調べていると、渡されたcsvファイルがWindowsで作ったものだったので、各行のおしりに'^M'がくっついているのが悪いんだということに気がつきました。しばらく悩んだ。

4月24日追記

CSVから切り出すときにchop()したほうがいいみたい。ソースすこしなおしました。