Имя генерируеться по шаблону. Шаблон состовляеться из руских букв. Например: лилу Если в скобках { } указать несколько букв, то случайно выберелться одна из них Пр: л{аоиу}у Сюда подойдут имена: лилу, лолу, лалу, .... В [ ] таких скобках указывается буквы которые идут "как есть" Пр: {[ди][по][ку][вы]} Это вернёт один из слогов: ди, по, ку, вы Вложеность есть: {[д{аоиу}][п{аоиу}][ку][вы]} Блоки и буквы можно домножать Пр: {[ди][по][ку][вы]}*3 Это эквивалентно: {[ди][по][ку][вы]}{[ди][по][ку][вы]}{[ди][по][ку][вы]} Пр: [а]*2 ~ [а][а] Пр: ли*2лу*3 ~ лиилууу То на что домножать можно указывать так 3-7 : случайно выберелься одно число от 3 до 7 Пр: [а]*2-4 Получиться либо [а][а], либо [а][а][а], либо [а][а][а][а]
Класс:
| Код |
class name_generator {
var $abc="абвгдеёжзийклмнопрстуфхцчшщъыьэюя"; //Шаблон нижнего регистра var $_abc="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; //Шаблон для перевода в нижний регистр var $num="0123456789"; //Шаблон цифр
var $from; //Число страта mt_srand var $type_up;
//----------------------------------------- // Stars //-----------------------------------------
function generet($mask,$from) { $this->from = $from; //Записываем значение
mt_srand($this->from); //Инициализируем mt_rand
$mask = $this->low($mask); //Переводим в нижний регистр
$name = $this->map($mask,"stat"); //По умолчанию шаблон в статических скобках [], запускаем анализатор
return $name; //Анализатор возвращает уже готовое имя }
//----------------------------------------- // Map Func Анализатор работает рекурсивно (первый параметр - маска, второй вызван из какой функции '{}' или '[]') //-----------------------------------------
function map($mask,$func) { $level=0; //Уровень вложености, для сбора подмаски $in_mask=""; //Вложенная маска $t=""; //Возврощаемое значение (часть готового имени) $now_up = ""; //Тип подмаски $oneof=array(); $in_numer=0; //Массив для хранения случаеных частей имени и ключ for($i=0; $i<strlen($mask); $i++) {
if($this->is_up($mask[$i])) //Проверям, является ли скобочкой откр. (также в $this->type_up <- тип скоб. ) { $level++; //Уровень вверх (Для того чтоб найти потом закрывающую скоб. первого уровня) if($level==1) //Если скобочка первого уроня (=0), то этот тип и будет типом подмаски { $now_up = $this->type_up; //Он нам нужен щас, $this->type_up потом измениться continue; //На следующий шаг цикла, ТАК КАК нам не нужно сознонять в подмаске эту скоб. } }
if($this->is_down($mask[$i])) //Закр. скобка { $level--;
if($level==0) //Ищем закрывающую скобку первой скобки { $n=""; //Умножение скоб. $n2=""; //Второе число по умножению
if($mask[$i+1] == '*') //Если есть умножение ищем n { $j=$i+1; //Ищем не другому индеску while( $this->is_num( $mask[++$j] ) )$n .= $mask[$j]; //Собираем число if( $mask[$j] == '-' && $n != "" ) //Если есть другое { while( $this->is_num( $mask[++$j] ) )$n2 .= $mask[$j]; //Собираем и его if($n2 > $n) { $n = mt_rand( $n , $n2 ); //Выбираем из чисел } //Смещение на '-' $i++; } $i++; //Смещение на '*' } if($n == "") //Нашли ли умножение? { $n = 1; } else { $i += strlen($n)+strlen($n2); //Ага, тогда смещаем индекс на число знаков в цифрах (на *,- уже сместили) }
for($j=0; $j<$n; $j++) //Несколько раз ( 1 - n ) бызываем рекурсивную функцию для подмаски с её типом if($func == "map")$oneof[ $in_numer++ ] = $this->map($in_mask,$now_up); //Собираем для выбора else if($func == "stat")$t .= $this->map($in_mask,$now_up); //Собираем для возврата
$in_mask = ""; //Очищаем подмаску для поиска следующей на уровне один continue; //Прыгаем, закрывающая скобка нам не нужна } } if($level > 0) //Собираем подмаску, если мы не на первом уровне $in_mask .= $mask[$i];
if($level == 0) //Готовим для возврата { $n=""; //Первое число $n2=""; //Второе $t_add = $mask[$i]; //Сохроняем умножаемую букву if($mask[$i+1] == '*') //Если умножение букв? Умножаем - так же { $j=$i+1; //Индекс для поиска while( $this->is_num( $mask[++$j] ) )$n .= $mask[$j]; //Ищем if( $mask[$j] == '-' && $n != "" ) //Есть другое число? (n-n2) { while( $this->is_num( $mask[++$j] ) )$n2 .= $mask[$j]; //Ищем другое if($n2 > $n) { $n = mt_rand( $n , $n2 ); //Выбираем одно число } //Смещение $i++; } $i++; //Смещение }
if($n == "") //Если вообще нет чисел { $n = 1; } else { $i += strlen($n)+strlen($n2); }
for($j=0; $j<$n; $j++) if($func == "map")$oneof[ $in_numer++ ] = $t_add; //Собираем массив для выбора в возврат else if($func == "stat")$t .= $t_add; //Собираем строку
}
}
if($func == "map") //Тип функции выборка { $grand = mt_rand( 0 , count($oneof)-1 ); //Выбираем случайный элемент
return $oneof[$grand]; //Возвращаем его } else if($func == "stat") //Тип - строка { return $t; } }
//----------------------------------------- // Help Func //-----------------------------------------
function is_up($c) { if($c == '[') { $this->type_up = "stat"; return true; } if($c == '{') { $this->type_up = "map"; return true; } return false; }
function is_down($c) { if($c == ']') { return true; } if($c == '}') { return true; } return false; }
function is_num($n) { $return = ($n=="") ? false : true; for($i=0; $i<strlen($n); $i++) { $in=false; for($j=0; $j<strlen($this->num); $j++) if( $n[$i] == $this->num[$j] ) $in = true;
if(!$in)$return = false; } return $return; }
function low($str) { return strtr($str,$this->_abc,$this->abc); }
}
|
Вызов:
| Код | $gen = new name_generator;
$start = time();
$name .= $gen->generet( $_POST['mask'] , $start )
|
$start - типа ключа к имени
Попробовать можно тут: http://mellon.ru/namegenerator/
Посмотрите пожалуйста! Если какие-нибудь баги? Как можно улучшить?
Если кто придумает хороший шаблон для имени - давайте сюда! |