8자리의 랜덤 문자열을 작성하는 함수 rand8()

8자리의 랜덤 문자열을 작성하는 함수 rand8()

특정 자리수의 랜덤한 문자열을 20만건 작성해야 할 일이 생겨서 급하게 만들어봤다.
제한 조건으로는 절대로 겹치면 안된다는 것.
겹치지 않는 조건을 충족하기 위해 MySQL까지 동원해서 Unique성을 체크했다.

의외로 넷 상의 많은 공개 함수들이 엉터리였다.
또한 문자열 속에 포함되어야 하는 문자, 포함안될 문자를 설정하는 기능도 약했다.
우연히 구한 잘 된 함수 rand8()을 기록해 둔다.

정말 아쉽게도, 원래 출처였던 외국사이트의 공개 주소를 잃어버린 것 같아 죄송하다.
아래에 8자리의 랜덤 문자열을 작성하는 함수 rand8()에 대한 예제이다.
상단부 소스는 실패한 여타 함수들도 함께 있다.


set_time_limit( 10000 );

function make_seed()
{
list($usec, $sec) = explode(' ', microtime());
return (float) (($sec + $usec ) * 100);
}

function VISION_TO_RANDOM
(
// autor Femi Hasani [www.vision.to]
$length=7, // string length
$uselower=1, // use lowercase letters
$useupper=1, // use uppercase letters
$usespecial=1, // use special characters
$usenumbers=1, // use numbers
$prefix=''
)
{

$key = $prefix;
// Seed random number generator
// mt_srand((double)microtime() * rand(1000000, 9999999));
mt_srand( make_seed()*100 );

$charset = "";
if ($uselower == 1) $charset .= "abcdefghjkmnpqrstuvwxyz";
// if ($useupper == 1) $charset .= "ABCDEFGHJKMNPQRSTUVWXYZ";
if ($usenumbers == 1) $charset .= "23456789";
// if ($usespecial == 1) $charset .= "~#$%^()_+-={}][";
while ($length > 0) {
$key .= $charset[rand(0, strlen($charset)-1)];
$length--;
}
return $key;
}


function range2($start, $end, $length)
{
$str_array = range($start, $end);
srand((double) microtime() * 1000000);
$text = '';
for($i = 0; $i < $length; $i++)
{
$text .= $str_array[rand(0, count($str_array) - 1)];
}
return $text;
}



function createRandomPassword() {
$chars = "abcdefghjkmnpqrstuvwxyz23456789";

srand((double)microtime()*1000000);

$i = 0;

$pass = '' ;
while ($i <= 7) {

$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}

if ( strlen( $pass) == 8 ) return $pass;
else false;
}

// SUCCESS!
function rand8() {
$len = 7;
$base='abcdefghjkmnpqrstuvwxyz23456789';
$max=strlen($base)-1;
$activatecode='';
mt_srand((double)microtime()*10000000); //// IMPORTANT!!!!! 10000000
while (strlen($activatecode)<$len+1)
$activatecode.=$base{mt_rand(0,$max)};

if ( strlen( $activatecode ) == 8 ) return $activatecode;
else false;
}


$conn = mysql_connect('localhost', 'www', 'www');
mysql_select_db( "test" );


while ( $ii < 10000000 ) {
// echo VISION_TO_RANDOM( 8 )."
";

// echo "insert into `serial8`(`sn`,`randvalue`) values ( NULL,'".VISION_TO_RANDOM( 8 )."');
";
// insert into `serial8`(`sn`,`randvalue`) values ( NULL,'8pawcvmh');

// $strSQL = "insert into `serial8`(`sn`,`randvalue`) values ( NULL,'".VISION_TO_RANDOM( 8 )."')";
$str = rand8();
if ( $str != false ) {
$strSQL = "insert into `serial8`(`sn`,`randvalue`) values ( NULL,'".$str."')";
}
// $strSQL = "insert into `serial8`(`sn`,`randvalue`) values ( NULL,'".range2( '2', 'z', 8 )."')";

$result = mysql_query( $strSQL );
if (!$result) {
// echo ('Invalid query: ' . mysql_error() . "
");
}
else
{
echo ('Inserted: ' . $strSQL . "
");
}

$ii++;
}

mysql_close( $conn );

/***
検証用SQL : randvalueフィールドはUnique条件
select count(1) from serial8 where length( randvalue )!=8
or randvalue like '%l%'
or randvalue like '%1%'
or randvalue like '%o%'
or randvalue like '%0%'
or randvalue like '%i%'
***/
?>



다음에 기회가 되면 이를 클래스화해서 공개하는 것도 좋을 것 같다.

우선 시간이 없어서 클래스화 했을 경우의 예제 소스를 기록해 둔다.


/**
* Uniqueな文字列をランダム生成するクラス
*
* PHP5.x用、PHP4.1.x系にも対応。
* このファイルはUTF-8フォーマット、TABの幅は4。
*
* @access public
* @create 2008/11/28
* @version v0.1
**/

/**********************************
************ 使用例 ************
**********************************

ini_set('memory_limit', '64M'); // 使用メモリの制限を伸ばす。(php.iniの設定が優先)
set_time_limit( 3600 ); // 実行時間を3600秒(1時間)まで伸ばす。
require_once "class.RandomUnique.php";

// 使用例 #1
$objRU = new RandomUnique(); // クラスのInstanceを生成。ランダム文字列のDefault桁数は8である。
$str = $objRU->getString( 10000 ); // 1万件のUniqueなランダム文字列を返す。文字列の各結果は改行(\n)で区別。
echo nl2br( $str );
$arr = $objRU->getArray( 200000 ); // 20万件のUniqueなランダム文字列を配列(以下'文字配列')で返す。

// 使用例 #2
$objRU2 = new RandomUnique( "abxy123789", 6 ); // クラスのInstanceを生成する際に「文字リスト」と「桁」を設定。
$arr2 = $objRU2->getArray( 10000000 ); // 1千万件のUniqueなランダム文字配列を返す。メモリ制限を越えるとエラーを配列で返す。

// 使用例 #3
$listChar = "abcdefghjkmnpqrstuvwxyz23456789"; // 「文字リスト」の準備。
$objRU3 = new RandomUnique( $listChar ); // クラスのInstanceを生成する際に「文字リスト」を設定。Default桁数は8である。
$objRU3->make( 30000 ); // 3万件のUniqueなランダム文字配列で生成する。既存のラン

ダム文字値は廃棄される。
$objRU3->save( "./output.txt" ); // ランダム文字列をファイル名output.txtで保存する。文字列の各結果は改行(\n)で区別。

// 使用例 #4
$objRU4 = new RandomUnique( null , 12 ); // ランダム文字列の桁数は12で設定。「文字リスト」がnullであればDefault値を使用。
$objRU4->setChar( "abcdfgxyz23456789!#%*@" ); // ランダム文字列の生成のため使う「文字リスト」を設定。Default値は a~z, 0~9。
$objRU4->setWidth( 10 ); // ランダム文字列を(12桁から)10桁で変更。最大ランダム数は「文字

リスト」の長さ^10件。
$objRU4->make( 40000 ); // 4万件のUniqueなランダム文字配列で生成する。既存のラン

ダム文字値は廃棄される。
$bUniq = $objRU4->isValid(); // 配列で生成されたランダム文字列がUnique性と桁数を満たすか検証(結果はtrue /

false)。
if ( !$bUniq ) var_dump($objRU4->getInvalid()); // ランダム文字列がUnique性を満たない場合、その原因である文字配列などを取得・表示。

**********************************/


class RandomUnique {


} // end of class RandomUnique

?>

by 혼수상태 | 2009/01/27 23:06 | 트랙백

트랙백 주소 : http://isma44.egloos.com/tb/4827115
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
※ 로그인 사용자만 덧글을 남길 수 있습니다.

◀ 이전 페이지 다음 페이지 ▶