【问题标题】:generate random String that must Contains alphabets, number and Special Character (6-10 digits)生成必须包含字母、数字和特殊字符(6-10 位)的随机字符串
【发布时间】:2014-07-05 17:33:59
【问题描述】:

我正在生成一个 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();
    }

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

我每次都想要字母和数字以及特殊字符的组合。有什么建议吗?

【问题讨论】:

  • 这样做有什么特别的原因吗?您需要满足任何特定的数量吗?
  • @JoachimIsaksson 我正在为忘记密码而开发它,并且那里的有效密码必须包含字母、数字和符号,我将其邮寄到用户电子邮件

标签: java scala random playframework passwords


【解决方案1】:

这是针对该问题的更惯用的解决方案,它提供了更好的 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

注意:此解决方案可以进行几轮优化。例如。 @tailrec, StringBuilder.

【讨论】:

  • 与标题中的问题不同,Random.alphanumeric 只生成 [A-Za-z0-9] 而不是特殊字符。 Scala 是否提供与您上面的答案类似的方法,然后才允许您传递自己的字符集?
【解决方案2】:
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();
    }

【讨论】:

  • 更改伪代码以过滤不需要的结果:sb.toString 为 allString 或 allNum
【解决方案3】:

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

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

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

【讨论】:

    【解决方案4】:

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

    (顺便说一句,我不熟悉 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())));
    }
    

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

    【讨论】:

    • @LOL for 循环是否会持续到 i 等于 len?我的错。再说一次,我对 Scala 不熟悉……我习惯从 0 开始,一直到 n - 1
    • @LOL 好吧。我将从我的答案中删除该部分并更改循环。对于造成的误解,我深表歉意。
    【解决方案5】:

    使用不可变数据结构更符合 scala 的习惯。以下代码有效。

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

    编辑: 为确保字符串中始终存在数字、特殊字符和字母,我将分别生成每个字母类别,然后以功能方式或简单地使用 Random.shuffle(characterList).mkString =D 随机连接它们。

    【讨论】:

      【解决方案6】:

      你可以应用while循环的原理。

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

      【讨论】:

        【解决方案7】:

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

        $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
        

        【讨论】:

          猜你喜欢
          • 2015-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-08
          • 1970-01-01
          • 2021-09-16
          • 2019-02-17
          • 2013-01-16
          相关资源
          最近更新 更多