Do Until循环只返回一个部分

时间:2012-08-27 08:21:04

标签: vb.net function vba loops

尝试在VB.NET中制作随机密码生成器

到目前为止已经有了这个,但它只返回我试图做的第一部分

我有3个输入密码类型作为复选框,按此顺序:

Numeric
Alphabetic
Symbols

如果我有数字选中它会返回一个数字密码,但如果我有数字和字母检查它只返回一个数字密码,但如果我取消选中数字并且只有字母选中它然后返回和字母密码

字母密码也有三个选项:

Uppercase
Lowercase
Mixed Case

当与字母一起使用时,实际上会返回正确的密码

这是我到目前为止的代码:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    C_Numeric.Checked = True
    R_Upper.Checked = True
End Sub

Private Sub B_Generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B_Generate.Click
    Dim c_a As Boolean = False
    Dim c_b As Boolean = False
    Dim c_c As Boolean = False
    Dim a As Integer
    If C_Numeric.Checked = True Then
        c_a = True
    ElseIf C_Alphabetic.Checked = True Then
        c_b = True
    ElseIf C_Symbols.Checked = True Then
        c_c = True
    End If
    If R_Lower.Checked = True Then
        a = 1
    ElseIf R_Upper.Checked = True Then
        a = 2
    ElseIf R_Mixed.Checked = True Then
        a = 3
    End If
    If C_Numeric.Checked = True Or C_Alphabetic.Checked = True Or C_Symbols.Checked = True Then
        TextBox1.Text = GenPass(NumericUpDown1.Value, c_a, c_b, c_c, a)
    End If
End Sub

Function GenPass(ByVal Length As Integer, ByVal Num As Boolean, ByVal Alp As Boolean, ByVal Ascii As Boolean, ByVal Complexity As Integer)
    Dim rand As New Random
    Dim Pass As String = ""
    Do Until Pass.Length = Length
        Dim a As Integer
        a = rand.Next(1, 3 + 1)
        If a = 1 And Num = True Then
            Pass += ChrW(rand.Next(Asc("0"), Asc("9") + 1))
        End If
        If a = 2 And Alp = True Then
            If Complexity = 1 Then
                Pass += ChrW(rand.Next(Asc("a"), Asc("z") + 1))
            ElseIf Complexity = 2 Then
                Pass += ChrW(rand.Next(Asc("A"), Asc("Z") + 1))
            ElseIf Complexity = 3 Then
                Dim b As Integer
                b = rand.Next(1, 2 + 1)
                If b = 1 Then
                    Pass += ChrW(rand.Next(Asc("A"), Asc("Z") + 1))
                ElseIf b = 2 Then
                    Pass += ChrW(rand.Next(Asc("a"), Asc("z") + 1))
                End If
            End If
        End If
        If a = 3 And Ascii = True Then
            Dim b As Integer
            b = rand.Next(1, 4 + 1)
            If b = 1 Then
                Pass += ChrW(rand.Next(Asc("!"), Asc("/") + 1))
            ElseIf b = 2 Then
                Pass += ChrW(rand.Next(Asc(":"), Asc("@") + 1))
            ElseIf b = 3 Then
                Pass += ChrW(rand.Next(Asc("["), Asc("`") + 1))
            ElseIf b = 4 Then
                Pass += ChrW(rand.Next(Asc("{"), Asc("~") + 1))
            End If
        End If
    Loop
    Return (Pass)
End Function

例如(假设所有答案的长度均为16):

选择带有混合大小写的数字和字母应返回:

eVOv3fyTmW7mvH24 CZOXVzeo1EzLu7Al V313p9VLW0Bz7Zfi 

但是返回:

8343299372194893 7303963979299152 3918539496952829

我还没有弄清楚为什么它实际上没有返回所需的结果

任何帮助将不胜感激

亚当

2 个答案:

答案 0 :(得分:3)

这是因为

If C_Numeric.Checked = True Then
    c_a = True
ElseIf C_Alphabetic.Checked = True Then
    c_b = True
ElseIf C_Symbols.Checked = True Then
    c_c = True
End If

因此,如果选中C_NumericC_Alphabeticc_a会获得True,但行c_bTrue的行设置将不会因ElseIf而被点击。

因此,请删除Else部分。


此外,您可以通过写入来简化此代码:

c_a = C_Numeric.Checked 
c_b = C_Alphabetic.Checked 
c_c = C_Symbols.Checked 

代替If子句,或者更好,通过调用来消除那些不必要的变量:

GenPass(NumericUpDown1.Value, C_Numeric.Checked, C_Alphabetic.Checked, C_Symbols.Checked, a)

还有很多改进可能。例如,不要将Complexity参数作为Integer传递,而是创建Enum

Enum Complexity
    LowerOnly
    UpperOnly
    Mixed
End Enum

Function GenPass(Length As Integer, Num As Boolean, Alp As Boolean, Ascii As Boolean, Complexity As Complexity)

如果您使用的是VB 10.0(随.Net 4.0一起推出),您可以摆脱笨重的ByVal关键字。另外,.Net Naming Guidelines in。


更多说明:

如果您正在检查If子句中的布尔值,则无需显式写= True

If a = 3 And Ascii = True Then

可以写成

If a = 3 AndAlso Ascii Then

请注意,AndAlso通常更适合And,因为它的行为很短。

另外,更好地命名参数useAcii而不是Acii。它会使它更清晰。

答案 1 :(得分:0)

您可以使用以下代码获得所需的结果。

If C_Numeric.Checked = True Then
    c_a = True
End If
If C_Alphabetic.Checked = True Then
    c_b = True
End If
If C_Symbols.Checked = True Then
    c_c = True
End If