0

我在制作一个包含 8 个不同字符的数组时遇到问题,每个字符都取自 3 个不同的 char 数组之一(一个包含严格的小写字符,第二个只包含大写字符,第三个只包含数字)。

问题是,它应该一次从随机字符数组中获取 1 个字符。

我的包含每组字符的数组在这里声明:

Dim lcase() As Char = "abcdefghijklmnopqrstuvwxyz".ToCharArray()
Dim ucase() As Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
Dim num() As Char = "0123456789".ToCharArray()
Dim chars(7) As Char

至于填充最终数组的代码(在我的例子中是 chars(7)):

Dim lim As Short = rand.Next(1, 5)
For x = 0 To lim
    Dim char_num As Integer = rand.Next(0, lcase.GetUpperBound(0))
    chars(x) = lcase(char_num)
Next
Dim lim2 As Short = 6 - lim
For x = 0 To lim2
    Dim char_num As Integer = rand.Next(0, num.GetUpperBound(0))
    chars(x) = num(char_num)
Next
For x = 0 To 6 - lim2
    Dim char_num As Integer = rand.Next(0, ucase.GetUpperBound(0))
    chars(x) = ucase(char_num)
Next

这是可行的,尽管由于某种原因它倾向于(出于某种原因)将某些值保留为空,最终导致我得到如下输出:

QHK M  D
 LCR86  

我需要的是让我的代码正确地填充数组,因此它包含正确的值,每个值都取自三个 char 数组。

注意: mychars(7)被声明为Char因为我在生成后交换了其中包含的字符,以从这些字符中创建一个完全随机的字符串。

我怀疑我在填充数组的代码中的某个地方犯了一个错误,但如果我的错误不在上面的代码中,这里是随机化chars()数组中字符顺序的代码:

Dim j As Integer
Dim swap As Char
Dim r As Random = New Random()

For i As Integer = 0 To chars.GetUpperBound(0)
    j = r.Next(0, i)
    swap = chars(j)
    chars(j) = chars(i)
    chars(i) = swap
Next i

提前谢谢各位。

更新:我意识到我的错误,for循环不断覆盖已经添加到数组中的内容,从而使最后几个位置保持打开状态。我现在需要的只是一种让它们正确添加到第一个空插槽的方法。

4

3 回答 3

1

我想你可能有点想多了。一个直接使用 ASCII 代码查找字符的简单函数可能会更简单,更容易调试。像这样的东西:

Private Function GenPass() As Char()
    Dim OutVal(7) As Char
    Dim nextchar As Char
    Dim rand As New Random(Now.Millisecond)
    For I = 0 To 7
        Do
            nextchar = Chr(rand.Next(48, 122))

        Loop Until Not OutVal.Contains(nextchar) AndAlso Not (nextchar > "9"c AndAlso nextchar < "A"c) AndAlso Not (nextchar > "Z"c AndAlso nextchar < "a"c)
        OutVal(I) = nextchar
    Next
    Return OutVal
End Function

输出是一个带有随机字母数字值的 Char 数组。这是一个这样的输出:

?GenPass
{Length=8}
    (0): "L"c
    (1): "l"c
    (2): "W"c
    (3): "8"c
    (4): "P"c
    (5): "E"c
    (6): "c"c
    (7): "2"c
于 2013-09-15T02:35:17.067 回答
0

最终自己找到了解决方案,我的初始代码一直覆盖第一个值,而不是继续上一个循环停止的数组。

这是实际工作的代码:

Dim lcase() As Char = "abcdefghijklmnopqrstuvwxyz".ToCharArray()
Dim ucase() As Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
Dim num() As Char = "0123456789".ToCharArray()
Dim chars(7) As Char

Dim lim As Short = rand.Next(1, 6)

For x = 0 To 7
    Dim char_num As Integer = rand.Next(0, lcase.GetUpperBound(0))
    chars(x) = lcase(char_num)
Next

For x = 0 To lim
    Dim char_num As Integer = rand.Next(0, num.GetUpperBound(0))
    chars(x) = num(char_num)
Next

lim = rand.Next(1, 5)

For x = 0 To lim
    Dim char_num As Integer = rand.Next(0, ucase.GetUpperBound(0))
    chars(x) = ucase(char_num)
Next
于 2013-09-15T03:18:41.240 回答
0

为什么是 3 个单独的数组?为什么不是一个包含您的“字母表”的大字母,如下所示:

Dim alphabet() As Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray()

我现在可以听到你说,“但是我怎么知道它是从每个字符集中挑选出来的?”。部分答案是它不是真正随机的,除非有机会从数组中选择零次。另一部分是,如果您真的需要,您可以随时验证输出并重新滚动。

这为您提供了更简单的代码:

Dim alphabet() As Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray()
For x As Integer to chars.Length - 1
   chars(x) = rand.Next(0, alphabet.Length)
Next
Return New String(chars)

而已。这就是全部。也没有必要对这些结果进行洗牌。

另一个不错的功能是它可以轻松调整您的字母表。例如,在将这些代码传达给最终用户时,从字母表中删除某些字符以避免混淆通常很有用。为此,现在您只需要更改一个字符串:

Dim alphabet() As Char = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789".ToCharArray()

如果您仔细查看,您会发现缺少三个字符:大写“O”、小写“L”和数字“0”。通过省略这些字符并确保选择一种能够正确区分其他字符的字体(Courier New 可以使用,但大多数可变宽度字体需要删除更多字符),您可以避免大量呼叫帮助台。

于 2013-09-15T04:56:04.253 回答