PHP+MySQL生成不重复随机数

能力有限,希望以后有更加好的方法.  

特此发上来留念.

比较波折的一次随机数生成过程,利用了数据库的唯一索引特性避免了随机数重复出现,然后循环生成直到结束.

1、MySQL 数据库准备

CREATE TABLE IF NOT EXISTS `randcode` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `code` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `code` (`code`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

2、PHP 代码

不做太多注释,偷懒.

<?php

set_time_limit(0);

class db
{
	private $host = 'localhost';
	private $user = 'root';
	private $pass = '123123';
	private $db   = 'databases';
	private $charset = 'utf8';
	private $con  = NULL;
	private static $_instance = NULL;
	
	public function __construct()
	{
		$this->con = mysql_connect($this->host, $this->user, $this->pass);
		
		if ( ! $this->con)
			die('Could not connect: '. mysql_error());
		else
		{
			mysql_set_charset($this->charset, $this->con);
			mysql_select_db($this->db, $this->con) or die ('Can\'t use databases : '. mysql_error());
		}
	}
	
	public static function insert($code)
	{
		if(NULL === self::$_instance)
			self::$_instance = new self;
		$sql = "INSERT INTO `randcode`(`code`)VALUES('$code')";
		return mysql_query($sql, self::$_instance->con);
	}
}

/**
 * 批量生成随机码
 */
class randcode extends db
{
	#字符池
	private $pattern = '1234567890';
	
	#基本参数
	private $num = 10;
	private $length = 9;
	private $key = NULL;
	private $temp_key = NULL;
	
	#防伪码参数
	private $forgery = true;
	private $forgery_key = 8;
	private $forgery_len = 5;
	
	#阻止指定位数出现特定字符
	private $prevent = true;
	private $prevent_default = '5';
	private $prevent_rule = array(
		array(1, 0),
	);
	
	public function __construct($num, $length=9)
	{
		$start_time = microtime(true);
		
		if ( ! empty($num))$this->num = $num;
		if ( ! empty($length))$this->length = $length;
		
		$i = 0;
		while ($i < $this->num)
		{
			$code = $this->randkeys();
			if (db::insert($code))
				$i++;
		}
		echo (microtime(true)-$start_time) .'s +done';
	}
	
	public function randkeys()
	{
		unset($this->key);
		
		$len = intval(strlen($this->pattern)-1);
		
		for ($i=0;$i<$this->length;$i++)
		{
			unset($this->temp_key);
			
			if ($this->forgery)
			{
				if (($this->forgery_len-1) == $i && $this->forgery_len != 0)
					$this->temp_key = $this->forgery_key;
				else
					$this->temp_key = $this->pattern{mt_rand(0, $len)};
			}
			else
				$this->temp_key = $this->pattern{mt_rand(0, $len)};
			
			if($this->prevent)
			{
				foreach($this->prevent_rule as $v)
				{
					if ($i == intval($v['0']-1) && $v['0'] != '0')
					{
						if($this->temp_key == $v['1'] && $v['1'] != $this->forgery_key)
							$this->temp_key = $this->prevent_default;
					}
				}
				$this->key .= $this->temp_key;
			}
			else
				$this->key .= $this->temp_key;
		}
		
		return $this->key;
	}
}
new randcode($_GET['n']);

最后通过地址栏传递参数(n=生成个数)即可. 整个生成过程效率一般,凑合使用.

你可能感兴趣的:(PHP,随机数,不重复)