Visual Basic密码生成器

时间:2017-01-04 08:20:25

标签: .net vb.net passwords generator

我的任务是创建一个可视化的基本随机密码生成器。我已经提出了下面的工作,但它的密码标准有点粗糙。我希望它生成的每个密码至少包含1个数字,大写和小写。然而,我如何对此进行编码会产生随机组合,这通常会导致错过其中一个标准。

我自己有一个游戏,我将有三个字符串,一个用大写字母,一个用小写字母,第三个用数字字符串。一旦它有一个,它将使用我的代码生成其余的密码。这听起来不是很干净,而且我一直遇到这样的问题。

任何人都可以帮助指出我正确的方向或协助下面的代码。密码长度必须介于6到20个字符之间。

提前致谢

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        TextBox2.Text = GenerateCode()
    End Sub

    Private Function GenerateCode() As Object
        Dim intRnd As Object
        Dim intStep As Object
        Dim strName As Object
        Dim intNameLength As Object
        Dim intLength As Object
        Dim strInputString As Object
        strInputString = "1234567890ABCDEFGHIJKLMEOPQRSTUWXYZabcdefghijklmnopqrstuvwxyz"

        intLength = Len(strInputString)

        Randomize()


        strName = ""

        'Check for valid numeric entry
        If Integer.TryParse(TextBox1.Text, intNameLength) And intNameLength >= 6 And intNameLength <= 20 Then
            For intStep = 1 To intNameLength
                intRnd = Int((intLength * Rnd()) + 1)

                strName = strName & Mid(strInputString, intRnd, 1)

            Next
            GenerateCode = strName
        Else
            TextBox1.Text =("Please enter a valid password length")
        End If

    End Function
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        My.Computer.Clipboard.SetText(TextBox2.Text)

    End Sub

    Private Sub TextBox1_Enter(sender As Object, e As EventArgs) Handles TextBox1.Enter
        TextBox1.Text = ""
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub
End Class

==========更新==========

是的,我已经改变了我的代码,所以我现在有三个不同字符的字符串,1个用于鞋面,一个用于降低,一个用于数字。

这使我能够在表单中使用复选框功能。我玩了代码,它现在生成密码取决于我选择的复选框,正如我所说的很棒然而我总是保证,如果我选择,数字,上限和下限我会得到一个包含所有三个密码,有时密码只包含数字,即使检查了所有三个框。

猜测这与我只是要求它使用我提供的字符生成随机密码这一事实有关,并且没有验证它已经使用了所有这三个选项。

对此的任何帮助都会很棒。我正在努力,我不只是发帖,希望有人能为我做这项工作。如果有人能指出我正确的方向会很棒。

这是我的新代码。

Public Function GenerateCode()
    Dim intRnd As Integer
    Dim intStep As Integer = Nothing
    Dim strname As String
    Dim intlength As Integer
    Dim strinputstring As String = ""
    Dim Numbers As String = "12345678901234567890"
    Dim Lower As String = "abcdefghijklmnopqrstuvwxyzyz"
    Dim Upper As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZYZ"
    Dim intnamelength As Integer = 1


    If CheckBox1.Checked Then strinputstring &= Lower
    If CheckBox2.Checked Then strinputstring &= Numbers
    If CheckBox3.Checked Then strinputstring &= Upper

    intlength = Len(strinputstring)

    Integer.TryParse(NumericUpDown1.Text, intnamelength)

    Randomize()

    strname = ""

    For inStep = 1 To intnamelength

        intRnd = Int(Rnd() * intlength) + 1

        strname = strname & Mid(strinputstring, intRnd, 1)

    Next

    Return strname

End Function

4 个答案:

答案 0 :(得分:14)

这不依赖于UI控件,也不使用传统的.NET前VB函数。而是将变量传递给生成器,因此它与UI无关。它也不使用As Object,因为字符串是字符串。

<Flags>
Private Enum PasswordParts
    Upper = 1
    Lower = 2
    Numerals = 4
    All = 7
End Enum

Private Shared RNG As New Random()
Private Shared Numerals As String = "0123456789"
Private Shared Upper As String = "ABCDEFGHIJKLMNPQRSTUVWXYZYZ"
Private Shared Lower As String = "abcdefghijkmnopqrstuvwxyzyz"

Private Function GeneratePassword(length As Int32, 
             Optional pwparts As PasswordParts = PasswordParts.All) As String
    Dim PWCharPool As String = ""
    Dim PW As New List(Of String)()

    ' check the requested length
    If length < 6 Then length = 6
    If length > 20 Then length = 20

    ' build the pool and add the first of required characters
    ' for assure minimum conformance
    If pwparts.HasFlag(PasswordParts.Lower) Then
        PW.Add(Lower(RNG.Next(0, Lower.Length)))
        PWCharPool &= Lower
    End If
    If pwparts.HasFlag(PasswordParts.Upper) Then
        PW.Add(Upper(RNG.Next(0, Upper.Length)))
        PWCharPool &= Upper
    End If
    If pwparts.HasFlag(PasswordParts.Numerals) Then
        PW.Add(Numerals(RNG.Next(0, Numerals.Length)))
        PWCharPool &= Numerals
    End If

    ' pick the rest of the elements
    For n As Int32 = PW.Count To length - 1
        PW.Add(PWCharPool(RNG.Next(0, PWCharPool.Length)))
    Next

    ' shuffle the result so that the
    ' first 1-3 chars are not predictable
    Shuffle(PW, RNG)
    ' create a string from the result
    Return String.Join("", PW)
End Function
  • 请注意,没有小写L或大写O。用户01混淆,因此请将其删除或01(或两者)
  • 如果至少1个upper,lower和numbers的要求 hard ,则不需要If语句(不是块):只需从每个语句中选择一个将它们添加到池中之前的列表。您也不需要Enum或param。我根据问题中的代码离开了它们
    • 请注意,在调用此方法之前,您应该在单击 no 复选框时添加要处理的代码。
  • 可以使用StringBuilder来代替List(of String),但字符串非常短,以至于在您循环运行很多次之前,它确实无法节省任何时间即便如此,节省的时间也是微不足道的。

测试它:

Dim enumValues = [Enum].GetValues(GetType(PasswordParts)).Cast(Of Int32)()

For n As Int32 = 1 To 1000
    Dim style = CType(enumValues(RNG.Next(0, 4)), PasswordParts)
    Dim pwLen = RNG.Next(6, 21)

    Dim PW = GeneratePassword(pwLen, style)

    ' get riled up if the length does not match
    Debug.Assert(PW.Length = pwLen)
    Console.WriteLine("style: {0}  pw: '{1}' (len={2})", style, PW, PW.Length)
Next

示例输出:

  风格:上一页:&#39; QFHGPLIEEYPRP&#39; (LEN = 13)
  风格:所有pw:&#39; Z9Y3CoW&#39; (LEN = 7)
  风格:低级:&#39; tyghanjzudhhorfmvjr&#39; (LEN = 19)
  风格:所有pw:&#39; XyY3q10N6S&#39; (LEN = 10)
  风格:上一页:&#39; IOZGTTQTPCYLKGEFRZ&#39; (LEN = 18)
  风格:所有pw:&#39; 7t5CNMUM0GdWb&#39; (LEN = 13)
  风格:上轮:&#39; YIFXHRKEICOHXEUX&#39; (len = 16)

然后,帮助洗牌(这在某种程度上是可选的):

' Standared FY shuffle for List(Of T)
Public Sub Shuffle(Of T)(items As List(Of T), rnd As Random)
    Dim temp As T
    Dim j As Int32

    For i As Int32 = items.Count - 1 To 0 Step -1
        ' Pick an item for position i.
        j = rnd.Next(i + 1)

        ' Swap them.
        temp = items(i)
        items(i) = items(j)
        items(j) = temp
    Next i
End Sub

最大的问题是没有人能够记住这样的密码,因此它们被粘贴到显示器或键盘的底部。更好的方法是让用户选择PW并通过检查他们为长度和内容选择的字符串来验证它是否符合任何规则。这将允许my~MuffyDoodle123或某些用户可以记住。也许强迫他们定期更改它,并可能添加TrashCan来存储用户的旧PW,这样他们就无法在6或9个月内重复使用相同的PW。

自动生成令人难忘的PW的方法是使用单词。创建一个包含数千个形容词和副词的列表,以及几千个名词的另一个列表(比听起来容易 - 有在线生成器),你可以创建一个联合组合加一个特殊字符:

  

Rancid3Rain
  枯萎$耳语
  奶油/棉
  持久/帝国
  Maximum7Mist
  油腻/荣耀
  Vaporized_Vision
  有毒!泪
  生气!算盘

&#34; hard&#34;部分是使用集中列表并丢弃使用它们的单词,因此生成的密码中不会有重复的单词。只有当其中一个队列变低时,你才能重新开始。

答案 1 :(得分:1)

尝试:

这是基本的想法。如果您需要大写和小写字母,请将小写字母添加到字符串s。

Sub Main()
    Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    Dim r As New Random
    Dim sb As New StringBuilder
    For i As Integer = 1 To 8
        Dim idx As Integer = r.Next(0, 35)
        sb.Append(s.Substring(idx, 1))
    Next
    Console.WriteLine(sb.ToString())
    Console.ReadKey()
End Sub

这应该取代所有旧代码

答案 2 :(得分:0)

下面是我的照片。它对我来说效果很好,所以我相信它也将对您有用。 这样可以确保您的密码包含4个类别的组合,即:

  1. 大写
  2. 小写字母
  3. 数字
  4. 特殊字符

密码的最小长度为6个字符。

第一部分从4个类别中选择一个字符。然后,循环将运行所需的其余剩余字符数。由于前4个将按所列类别的顺序排列,因此在生成执行随机改组的密码后会添加一个改组代码,从而提高了密码的随机性。

Public Function GeneratePassword(Optional ByVal Len As Integer = 8)

    If Len < 6 Then 
       MsgBox("Minimum password length is 6 characters", MsgBoxStyle.OkOnly, "Minimum Length Reset")
       Len = 6
    End If

    Dim pass As String = String.Empty

    Dim nums As String() = "2 3 4 5 6 7 8 9".Split(" ") 'Omit 1 & 0
    Dim lettU As String() = "A B C D E F G H J K L M N P Q R S T U V W X Y Z".Split(" ") 'Omit i,I,o & O
    Dim lettL As String() = "A B C D E F G H J K M N P Q R S T U V W X Y Z".ToLower.Split(" ") 'Omit i,I,l, L,o & O
    Dim chars As String() = "(-) @ # $ % * {-} [-] - _ ^ < > + = ~ /\".Split(" ") 'omit ? / \ ( ) ' " . , ; : &

    Dim passRan() As Array = {nums, lettU, lettL, chars}

    Dim min As Integer = 0
    Dim max As Integer = passRan.Length 'this will include the length
    Dim rnd As Integer = 0

    Dim sb As New List(Of String)

    For l As Integer = 0 To Len - passRan.Length - 1
        'select the set to pick from ensuring you have a character from each set
        If l = 0 Then
            For p As Integer = 0 To passRan.Length - 1
                'pick a random position in the selected set
                max = passRan(p).Length
                rnd = GetRandom(min, max)
                sb.Add(passRan(p)(rnd))
            Next
        End If

        'select the set to pick from by random
        max = passRan.Length
        rnd = GetRandom(min, max)
        For p As Integer = 0 To passRan.Length - 1
            'pick a random position in the selected set
            If p = rnd Then
                max = passRan(p).Length
                rnd = GetRandom(min, max)
                sb.Add(passRan(p)(rnd))
                Exit For
            End If
        Next
    Next

    'shuffle the result
    Dim R As New List(Of String)
    R = sb.ToList
    For Int As Integer = 0 To Len - 1
        Dim curr As Integer = GetRandom(min, R.Count)
        pass &= R(curr)
        R.RemoveAt(curr)
    Next

    Return pass

End Function

Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
    Static Generator As System.Random = New System.Random()
    Return Generator.Next(Min, Max)
End Function

注意:为了增加可用的特殊字符的数量和复杂度,我使用了(-),[-]和{-},因为它们很难单独阅读,但是如果不加上它们也会很困难。之间的空间。我通常也更喜欢从密码中省略OoiIlL01,以减少混乱。

答案 3 :(得分:0)

这是我的密码生成器版本。也许有人会发现这很有用。它由 2 个函数组成,但您只调用 CreatePassword,它将适当的要求作为参数。它还验证需求,直到它们得到满足。我确定还有其他方法,但这对我有用。您可以添加符号,但必须修改代码。假设您想要一个 16 个字符长的密码,至少有 2 个大写字符、至少 2 个小写字符和至少 2 个数字字符。您可以像这样调用 CreatePassword:

Imports System.Text.RegularExpressions

Dim MyPassword As String = CreatePassword(16, 2, 2, 2)

这是我用于 CreatePassword 函数的代码

Private Function CreatePassword(ByVal inlength As Integer, numUpperChars As Integer, numLowerChars As Integer, numNumberChars As Integer) As String
    Dim funcResult As String, validCount As Boolean
    Do
        validCount = True
        funcResult = GetAPasswordString(inlength)

        Dim upper As New Regex("[A-Z]")
        Dim lower As New Regex("[a-z]")
        Dim number As New Regex("[1-9]")

        ' Check for minimum number of occurrences.
        If upper.Matches(funcResult).Count < numUpperChars Then validCount = False
        If lower.Matches(funcResult).Count < numLowerChars Then validCount = False
        If number.Matches(funcResult).Count < numNumberChars Then validCount = False

    Loop Until validCount
    Return funcResult
End Function

GetAPasswordString 函数代码

Private Function GetAPasswordString(ByVal length As Integer) As String
    ' excludes ambiguous characters i1I0Oo 
    Const ValidChars As String = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
    Dim result As New Text.StringBuilder
    Dim rnd As Random = New Random()

    While 0 < Math.Max(Threading.Interlocked.Decrement(length), length + 1)
        result.Append(ValidChars(rnd.[Next](ValidChars.Length)))
    End While
    Return result.ToString
End Function