RSS

Haskellでパスワード生成

まあSystem.Entropyを使って乱数の初期化をしてみたかったというだけなんだが…。ほんとにこれが真に安全な初期化なのかどうかはわからない。

乱数列からパスワードを生成する処理も気に食わない。

{-# LANGUAGE DeriveDataTypeable #-}

import Crypto.Random
import System.Entropy
import System.Random
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import Data.Word
import Data.List.Split
import System.Console.CmdArgs


pass_str_l = ['a'..'z']
pass_str_u = ['A'..'Z']
pass_str_n = ['0'..'9']
pass_str = BS8.pack (pass_str_l ++ pass_str_u ++ pass_str_n)

data Opts = Opts {
  opt_length :: Int, 
  opt_number  :: Int
  } deriving (Show, Data, Typeable)
  

opts = Opts {
  opt_length   = 8
                 &= explicit 
                 &= name "length" 
                 &= help "password length"
  , opt_number  = 10
                 &= explicit 
                 &= name "number" 
                 &= help "number of password" 
  } &= summary "Hoge foo bar"
     
main = do
  args <- cmdArgs opts
  entropy <- getEntropy 16
  let rs = randomRs (0, (BS8.length pass_str - 1)) (mkStdGen (bs2int entropy))
  mapM_ putStrLn (splitEvery (opt_length args)
            (map (\x -> BS8.index pass_str x) 
             (take ((opt_length args) * (opt_number args)) rs)))
  where 
    bs2int bs = BS.foldl shift8 0 bs
    shift8 i w8 = i * (2^8) + (fromIntegral (toInteger w8))