繁体   English   中英

生成随机字符串,该字符串必须包含字母,数字和特殊字符(6-10位数字)

[英]generate random String that must Contains alphabets, number and Special Character (6-10 digits)

我正在生成一个6到10位数字的密码。

这是我的代码,可为我提供6-10位数的随机密码,

val AB = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:<=>?@_!#%&()*+,-.~";
val rnd = new Random();

def randomPassword(): String = {
    val len = rnd.nextInt(5) + 5
    val sb = new StringBuilder(len);
    for (i <- 0 to len)
       sb.append(AB.charAt(rnd.nextInt(AB.length())));
    return sb.toString();
    }

它工作正常,但问题在于有时它会给出所有数字或字母

我希望每次都由字母,数字和特殊字符组成。 有什么建议吗?

首先生成一个包含所有字母的随机密码,然后根据需要将一些字母替换为数字/特殊字符。

(顺便说一句,我对Scala并不熟悉,所以我将使用Java的语法,因为我不知道自己是否要输入有效的东西。我很抱歉。)

// Split source string into letters, numbers, and specials
String AB = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String numbers = "0123456789";
String specials = ":<=>?@_!#%&()*+,-.~";

String randomPassword() {
    StringBuilder sb = new StringBuilder();
    int len = rnd.nextInt(5) + 5;

    // Generate password with letters first. This part is the same as the original code.
    for (int i = 0; i <= len; i++) {
         sb.append(AB.charAt(rnd.nextInt(AB.length())));
    }


    // Generate an index to replace with a number
    int numberIndex = rnd.nextInt(len);
    // Generate an index to replace with a special character
    int specialIndex;
    do {
        specialIndex = rnd.nextInt(len);
    } while (specialIndex == numberIndex);
    // Replace one letter with a number
    sb.setCharAt(numberIndex, numbers.charAt(rnd.nextInt(numbers.length())));
    // Replace one letter (or the number if you're unlucky) with a special character
    sb.setCharAt(specialIndex, specials.charAt(rnd.nextInt(specials.length())));
}

这是一个开始,有一个缺陷(只有一个数字+特殊字符),但是很容易修复。 如果不满足您的条件,此解决方案比生成全新的密码更有效,并且可以保证在方法返回时可以使用该密码。

def randomPassword(): String = {
    val len = rnd.nextInt(5) + 5
    val sb = new StringBuilder(len);
    for (i <- 0 to len)
       sb.append(AB.charAt(rnd.nextInt(AB.length())));

    if(sb.toString is allString or allNum){
       return randomPassword();
    }
    return sb.toString();
    }

简单的解决方案恕我直言是(伪代码)

generate password
if no alphabet;
    if not max length;
        add an alphabet
    else
        change last letter with an alphabet
if no digit;
    if not max length;
        add an digit
    else
        change first letter with an digit
if no special;
    if not max length;
        add an special
    else
        change second letter with an special

除非您已经有最大长度的密码,否则这绝不会减少熵。

使用不可变的数据结构对scala来说更惯用。 以下代码有效。

  protected def nextChar(): Char = Random.nextPrintableChar()

  def randomString(length: Int = 10): String = {
    (0 until length).map(_ => nextChar()).mkString
  }

编辑:为了确保字符串中始终有数字,特殊字符和字母,我将分别生成每个类别的字母,然后以功能方式或仅通过Random.shuffle(characterList).mkString = D随机将它们连接起来。

这是针对该问题的更惯用的解决方案,它提供了更好的API。

object password {
  import scala.util.Random
  import scala.collection.immutable.Stream


  private def gen = Random.alphanumeric

  def get(len: Int): String = {    
    def build(acc: String, s: Stream[Char]): String = {
      if (s.isEmpty) acc
      else build(acc + s.head, s.tail)
    }

    build("", gen take len)
  }
}

让我们生成一些密码

1 to 25 foreach { _ => println(password get 8) }

您会看到类似

YBk2UrOV
GD4eLexS
l8yxAkp9
ooQnaRpd
NgHAruB8
pMXpi4ad

注意:此解决方案可以进行几次优化。 例如@tailrecStringBuilder

您可以采用while循环的原理。

  1. 将附加的密码存储到变量中。
  2. 使用while循环检查它是否不包含数字和/或符号,如果不包含,请再次重新生成密码并将其存储到变量中。
  3. 当while循环自动中断时,返回变量。

您可以尝试这个,它对我有用。

$length = 45;
$chars = array_merge(range(0,9), range('a','z'), range('A','Z'));
shuffle($chars);
$password = implode(array_slice($chars, 0, $length));

echo "This is the password: ".$password;

输出示例:

This is the password: wmU7KaZoOCIf4qn2tz5E06jiQgHvhR9dyBxrFYAePcDWk

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM