<?php
if(isset($_GET['source'])) {
    
highlight_file(__FILE__);
    exit;
}
/**
 *
 * @author Zjmainstay
 * @website http://zjmainstay.cn
 * @copyright GPL
 * @version 1.0
 * @year 2014
 *
 */

//CLI Usage: php createPassword.php length=32\&type=all\&splitChar=_\&splitLength=4\&times=5

//动态开启错误提示
ini_set('display_errors','on');        // 'off' 关闭
error_reporting(E_ALL);

//默认长度和类型
$length         8;
$type           'number-lower-upper';
$customStr      '';
$splitChar      '';
$splitLength    4;
$times          10;
$isCli          = (PHP_SAPI=='cli') ? true false;

if(
$isCli) {
    if(!empty(
$argv[1]) && (($argv[1] == '--help') || ($argv[1] == '-h'))) {
        echo 
"Usage:        php createPassword.php length=32\\&type=number-lower-upper\\&splitChar=_\\&splitLength=4\&times=5\n";
        echo 
"length:       length of password\n";
        echo 
"type:         password with which type of char, can be: number/lower/upper/special join by '-', or 'all' for all char and 'custom' for custom str\n";
        echo 
"customStr:    you can use type=custom to custom string for you password just like customStr=123456, and it will create password by use 123456\n";
        echo 
"splitChar:    split char for password, default is empty so that password just like connect one by one\n";
        echo 
"splitLength:  split password by every splitLength step\n";
        echo 
"times:        create how many password in one time\n";
        exit;
    }
    
    if(!empty(
$argv[1])) parse_str($argv[1], $_POST);
    else 
$_POST = array(
        
'length'        => $length,
        
'type'          => $type,
        
'customStr'    => $customStr,
        
'splitChar'     => $splitChar,
        
'splitLength'   => $splitLength,
        
'times'         => $times,
    );
}

if(!empty(
$_POST)) {
    
/**
     *  获取随机密码函数
     *  @param string $type 密码字符串类型
     *  @param string $customStr 自定义密码组成字符
     *  @param int    $length 密码长度
     *  @param string $splitChar 分隔符,默认不分隔
     *  @param int    $splitLength 密码字符分隔长度 比如:密码为abc-def-ghi时$splitLength = 3
     *
     */
    
function getPassword($type 'number-lower-upper'$customStr ''$length 32$splitChar ''$splitLength 4) {
        
$strArr         = array(
            
'number'    => '0123456789',
            
'lower'     => 'abcdefghijklmnopqrstuvwxyz',
            
'upper'     => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
            
'special'   => '~!@#$%^&*()_+{}|[]\-=:<>?/',
        );
        
        if(
$type == 'all') {        //全部
            
$str implode(''$strArr);
        } else if(
$type == 'custom') {        //自定义类型
            
if(empty($customStr)) {    //未填写自定义类型,则默认为数字+大小写字母
                
$type    'number-lower-upper';
            } else {
                
$str     $customStr;
            }
        }
        
        
//custom 没带自定义类型 或 其他类型
        
if(empty($str)) {
            
$typeParts  explode('-'$type);
            
$str        '';
            foreach(
$typeParts as $part) {
                
$str   .= $strArr[$part];
            }
        }
        
        
$maxLength         500;    //最大长度
        
$length            = empty($length) ? $maxLength min((int)$length$maxLength);
        if(empty(
$length)) {
            
$length $maxLength;
        }
        
        
// 大数据下面str_shuffle会导致随机种子耗尽而导致结果循环(错误做法)
        // $passwordStr    = '';
        // do {
            // $randStr        = str_shuffle($str);
            // $passwordStr   .= substr($randStr, 0, 1);        //每次取一个字符
            // $passwordLength = strlen($passwordStr);
        // } while($passwordLength < $length);
         
        //纠正
        
$passwordStr    '';
        
$strMaxIndex    strlen($str) - 1;
        do {
            
$randIndex      mt_rand(0$strMaxIndex);
            
$passwordStr   .= $str[$randIndex];        //每次取一个字符
            
$passwordLength strlen($passwordStr);
        } while(
$passwordLength $length);

        
//需要分隔
        
if($splitChar != '') {
            
$passwordStr implode($splitCharstr_split($passwordStr$splitLength));
        }
        
        return 
$passwordStr;
    }
    
    
$length         = empty($_POST['length'])       ? $length       min(500$_POST['length']);
    
$type           = empty($_POST['type'])         ? $type         $_POST['type'];
    
$customStr      = empty($_POST['customStr'])    ? $customStr    $_POST['customStr'];
    
$splitChar      = empty($_POST['splitChar'])    ? $splitChar    $_POST['splitChar'];
    
$splitLength    = empty($_POST['splitLength'])  ? $splitLength  $_POST['splitLength'];
    
$times          = empty($_POST['times'])        ? $times        min(100max(1, (int)$_POST['times']));
    
    
$passwordArr    = array();
    for(
$i 0$i $times$i++) {
        
$passwordArr[] = getPassword($type$customStr$length$splitChar$splitLength);
    }
    
    
$password implode("\n"$passwordArr);
    
    if(
$isCli) {
        echo 
$password;
        exit;
    }
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>密码生成器</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="zh-CN" />
    <script type="text/javascript" src="http://www.zjmainstay.cn/jquerylib/jquery-1.8.2.min.js"></script>
</head>
<body>
<style type="text/css">
* {
    margin: 5px;
}
</style>
<form action="<?php echo $_SERVER['SCRIPT_NAME']?>" method="POST">
    <div>
    <label>长度:</label>
    <input type="text" name="length" value="<?php echo $length ?>" style="width: 100px;" placeholder="长度为0-32"/>
    </div>
    <div>
        <label>类型:</label>
        <select name="type" style="width: 150px;" id="type">
            <option value="number">纯数字</option>
            <option value="lower">小写字母</option>
            <option value="upper">大写字母</option>
            <option value="lower-upper">大小写字母</option>
            <option value="number-lower">数字+小写字母</option>
            <option value="number-upper">数字+大写字母</option>
            <option value="number-lower-upper">数字+大小写字母</option>
            <option value="special">特殊字符</option>
            <option value="number-special">数字+特殊字符</option>
            <option value="lower-special">小写字母+特殊字符</option>
            <option value="upper-special">大写字母+特殊字符</option>
            <option value="all">全部</option>
            <option value="custom">自定义</option>
        </select>
        <input name="customStr" type="text" size="100" value="<?php echo $customStr ?>"/>
    </div>
    <div>
        <label>密码分隔符(不填写则不分隔)</label>
        <input name="splitChar" type="text" value="<?php echo $splitChar ?>"/>
    </div>
    <div>
        <label>密码分隔长度</label>
        <input name="splitLength" type="text" value="<?php echo $splitLength ?>"/>
    </div>
    <div>
        <label>密码个数</label>
        <input name="times" type="text" value="<?php echo $times ?>"/>
    </div>
    <div>
    <input type="submit" value="生成"/>
    
    <?php if(!empty($password)) { ?>
    <div>
    <textarea id="password" readOnly="true" rows="<?php echo max(10$times 3); ?>" cols="80"><?php echo $password ?></textarea><span class="tips"></span>
    </div>
    <?php ?>
    </div>
</form>
<script type="text/javascript">
$(document).ready(function(){
    var strArr         = {
        'number'    : '0123456789',
        'lower'     : 'abcdefghijklmnopqrstuvwxyz',
        'upper'     : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'special'   : '~!@#$%^&*()_+{}|[]\-=:<>?/',
    };
    
    var updateCustomStrSize = function() {
        $("input[name=customStr]").attr("size", $("input[name=customStr]").val().length);
    }
    
    //更新自定义输出串内容
    var updateCustomStr = function() {
        var valueStr    = $("#type").val();
        var customStr   = '';
        if(valueStr == 'custom') {
            updateCustomStrSize();
            return true;
        } else if(valueStr == 'all') {
            $.each(strArr, function(i) {
                customStr  += strArr[i] || '';
            })
        } else {
            var parts       = valueStr.split('-');
            $.each(parts, function(i, type) {
                customStr  += strArr[type] || '';
            })
        }
        $("input[name=customStr]").val(customStr);
        updateCustomStrSize();
    }
    
    $("input[name=customStr]").on('keyup change', function() {
        if($("#type").val() != 'custom') {
            $("#type").get(0).selectedIndex = $("#type option").index($("#type option[value=custom]"));
        }
        updateCustomStrSize();
    });
    
    $("#type").change(function() {
        updateCustomStr();
    });
    
    //$("#password").click(function() {
        //$(this).select();
        //$(".tips").html("请使用 Ctrl + C 复制");
    //});
    
    //初始化默认选择数字+大小写字母
    $("#type").get(0).selectedIndex = $("#type option").index($("#type option[value=<?php echo $type ?>]"));
    updateCustomStr();
});
</script>
</body>
</html>