0

ランダムな文字を生成する 2 つのアルゴリズムの間で混乱します。小文字、大文字、数字、特殊文字の 4 つの文字タイプがあります。要求されたランダムな文字の種類に応じて、文字を生成する必要があります。例えば:

  • 要求されたのが純粋な小文字、大文字、数字、または特殊文字の場合、値は各タイプのみからランダムに選択する必要があります。
  • リクエストが小文字と数字の場合、その 2 つのタイプの混合文字列から選択する必要があります。

混合文字タイプに採用するアルゴリズムは次のとおりです。

  1. 要求された文字長の各タイプからランダムな文字列を選択します。
  2. これらの文字列を連結し、新しい文字列からランダムな文字を再度選択します。

このアルゴリズムは、各タイプがサンプル空間で利用できる確率が等しいことを保証すると思います。ただし、混合型の結果の文字列に、文字列に示されている型が 1 つも含まれていない場合があり、多くの場合、文字が繰り返されることがあります。

ランダムな文字列を選択する前にタイプを事前に混合することに依存する別のアルゴリズムがあります. ただし、1 つのタイプが存在しない可能性が高くなりますが、繰り返しは減少します.

各タイプのプレゼンテーションのバランスを提供し、繰り返しを減らす別のアルゴリズムがあるかどうかを知る必要がありますか?

以下は、最初に言及したアルゴリズムを実装するコードです。これは CakePHP 1.2.x コンポーネントであり、実際の例は次の場所にあります

<?php
class RandomStringComponent extends Object{
  var $name = 'RandomString';
  var $lowerCase = 'qwertyuiopasdfghjklzxcvbnm';
  var $upperCase = 'ASDFGHJKLQWERTYUIOPZXCVBNM';
  var $numbers = '9874563210';
  var $specialChars = '!@#$%)-+/}[<>~=,;:|`{.?]^&*(';
  var $outputForm = 'LcUcNuSp';
  var $settings = array();
  var $controller = null;      

  var $_defaults = array(
      'outputForm' => 'LcUcNuSp',
      'length' => 6
  );

  function initialize(&$controller, $settings){
    $this->settings = array_merge($this->_defaults, $settings);

  }

  function getRand($l = null){
    if (is_null($l)) $l = $this->settings['length'];
    switch ($this->settings['outputForm']){
      case 'Lc':
        return $this->_Lc($l);
        break;
      case 'Uc':
        return $this->_Uc($l);
        break;
      case 'Sp':
        return $this->_Sp($l);
        break;
      case 'Nu':
        return $this->_Nu($l);
        break;
      case 'LcUc':
        return $this->_setRand($this->_Lc($l).$this->_Uc($l),$l);
        break;
      case 'LcNu':
        return $this->_setRand($this->_Lc($l).$this->_Nu($l),$l);
        break;
      case 'UcNu':
        return $this->_setRand($this->_Uc($l).$this->_Nu($l),$l);
        break;
      case 'LcUcNu':
        return $this->_setRand($this->_Lc($l).$this->_Uc($l).$this->_Nu($l),$l);
        break;
      default:
        return $this->_setRand($this->_Lc($l).$this->_Uc($l).$this->_Nu($l).$this->_Sp($l),$l);
        break;
    }
  }


  function _Lc($l){
    $output = '';
    for ($i = 0; $i < $l; $i++){      
      $output .= $this->lowerCase[mt_rand(0, strlen($this->lowerCase)-1)];    
    }
    return $output;
  }
  function _Uc($l){
    $output = '';
    for ($i = 0; $i < $l; $i++){
      $output .= $this->upperCase[mt_rand(0, strlen($this->upperCase)-1)];    
    }
    return $output;
  }
  function _Sp($l){
    $output = '';
    for ($i = 0; $i < $l; $i++){
      $output .= $this->specialChars[mt_rand(0, strlen($this->specialChars)-1)];      
    }
    return $output;
  }
  function _Nu($l){
    $output = '';
    for ($i = 0; $i < $l; $i++){
      $output .= $this->numbers[mt_rand(0, strlen($this->numbers)-1)];    
    }
    return $output;
  }

  function _setRand($str, $l){

    $output = '';
    for ($i = 0; $i < $l; $i++){
      $output .= $str[mt_rand(0, strlen($str)-1)];    
    }
    return $output; 
  }  
}
?>
4

1 に答える 1

2

差し替えなしでサンプリングすることで、繰り返しをなくすことができます。「何らかの」繰り返しが必要な場合は、いくつかの k 値の繰り返しでサンプリングし、それを元のリストに追加し、置換せずにサンプリングします。

例: lowerCase = 'qwertyuiopasdfghjklzxcvbnm'

sampledLowercase = 小文字からのサンプル 5 文字 = 'abbcd'

これらは、置換なしで小文字 + サンプル小文字からサンプリングされます。

ここで、繰り返し文字を見つける確率は約 5/(26+5) = 5/31 です。sampledLowercase の長さが長いほど、文字が重複する可能性が高くなります。

于 2013-05-03T17:45:51.890 に答える