【问题标题】:C# Code generator with vowels and consonants, vowels not showing up带有元音和辅音的 C# 代码生成器,元音不显示
【发布时间】:2016-04-20 08:13:44
【问题描述】:

我有一个 C# 中的随机密钥生成器,它应该生成以下格式的密钥:

辅音+元音+辅音+元音+四位数字

例如,它将是 BABA1234 或 ZUZU9876。

然而,目前元音不显示,尽管其他所有内容都会显示,所以我最终会得到像 B_B_1234 这样的输出,例如,下划线表示空格或无法识别的字符框。

我一直在查看一些示例,例如 thisthisthis,但我仍然没有让它工作。 C#代码如下:

public static string shortText()
{
   string randomNumber = new Random().Next(1000, 9999).ToString();
   char c1 = consonant();
   char c2 = vowel();
   System.Threading.Thread.Sleep(400);
   char c3 = consonant();
   char c4 = vowel();

   return string.Format("{0}{1}{2}{3}{4}", c1, c2, c3, c4, randomNumber);
}

private static char vowel()
{
   int selected = new Random().Next(0, 4);
   List<int> list = new List<int> { 65, 69, 73, 79, 85 };

   return Strings.Chr(selected);
}

private static char consonant()
{
   int selected = new Random().Next(65, 90);
   List<int> list = new List<int> { 65, 69, 73, 79, 85 };

   if (list.Contains(selected) == false)
   {
       return Strings.Chr(selected);
   }
   else {
       return Strings.Chr(selected + 1);
   }
}

另外说明的是,这段代码最初是用VB编写的(这就是为什么上面的C#代码中有一个Strings.Chr,我添加了对VB库的引用),它可以正常工作并根据开头的格式。我将它转换为 C# 并稍微编辑它以消除错误,但看起来转换并不完美。这是VB代码:

Public Class Form1
    Private Sub btnGenerateKey_Click(sender As Object, e As EventArgs) Handles btnGenerateKey.Click
        txtKey.Text = shortText()
    End Sub

    Private Shared Function shortText() As String
        Dim randomNumber As String = New Random().Next(1000, 9999).ToString
        Dim c1 As Char = consonant()
        Dim c2 As Char = vowel()
        System.Threading.Thread.Sleep(400)
        Dim c3 As Char = consonant()
        Dim c4 As Char = vowel()

        Return String.Format("{0}{1}{2}{3}{4}", c1, c2, c3, c4, randomNumber)
    End Function

    Private Shared Function vowel() As Char
        Dim list As List(Of Integer) = New List(Of Integer)({65, 69, 73, 79, 85})

        Return Chr(list(New Random().Next(0, 4)))
    End Function

    Private Shared Function consonant() As Char
        Dim selected As Integer = New Random().Next(65, 90)
        Dim list As List(Of Integer) = New List(Of Integer)({65, 69, 73, 79, 85})

        If list.Contains(selected) = False Then
            Return Chr(selected)
        Else
            Return Chr(selected + 1)
        End If
    End Function
End Class

非常感谢任何帮助。

【问题讨论】:

    标签: c# vb.net random


    【解决方案1】:

    vowel() 正在返回随机数的值(即 1-4),而不是元音列表中的元素。

    通过修改来修复它

    return Strings.Chr(selected);
    

    return Strings.Chr(list[selected]);
    

    其他问题

    不过,您的代码还有一些其他问题。

    1) 您没有正确使用 Random。不要在每次需要随机数时都创建新的 Random 实例 - 创建一个实例并将其用于所有对随机数的请求。

    2) 由于您的算法,您更有可能得到辅音“b”、“f”、“j”、“p”、“v”。如果您在consonant() 中找到一个元音,而不是取下一个字母,您应该只拥有一个包含 21 个字符的列表,并从该列表中随机获取一个条目。

    3) 你为什么要创建一个ints 的列表来存储你的辅音?为什么不创建一个字符列表并避免强制转换。这样做会使您的实际错误立即显而易见,因为您会遇到编译错误:)

    【讨论】:

      【解决方案2】:

      为什么要编码 (65) 和解码 (Strings.Chr) 字符?为什么不直接

      private static Char[] s_Vowels = new Char[] {
        'A', 'E', 'I', 'O', 'U',
      };
      
      private static Char[] s_Consonants = new Char[] {
        'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 
        'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z',
      };
      
      // Simplest, not thread safe
      private static s_Random = new Random();
      
      private static String shortText() {
        StringBuilder sb = new StringBuilder(8);
      
        sb.Append(s_Consonants[s_Random.Next(s_Consonants.Length)]);
        sb.Append(s_Vowels[s_Random.Next(s_Vowels.Length)]); 
        sb.Append(s_Consonants[s_Random.Next(s_Consonants.Length)]);
        sb.Append(s_Vowels[s_Random.Next(s_Vowels.Length)]); 
      
        sb.Append(s_Random.Next(1000, 10000));
      
        return sb.ToString();
      }
      

      【讨论】:

      • 一件小事:s_Random.Next(1000, 9999) 永远不会返回值 9999。它只会上升到 9998。Next 的第二个参数是 exclusive 上绑定。
      • @Chris Dunawa:谢谢!你说的很对:我应该复制并粘贴问题中的片段。
      【解决方案3】:

      因为您没有在随机函数和元音列表中获取字母值。 字母以 ASCII 65 开头并向前。 您的代码应如下所示:

      private static string vowel()
      {
         var random = new Random();
         var list = new List<int> { 65, 69, 73, 79, 85 };
         return Strings.Chr(list[random.Next(0, 4)]);
      }
      

      consonant 也有同样的问题。
      为了获得良好的“随机性”,您不应每次都实例化一个新的 Random 对象,而应将其作为类中的成员字段并在所有方法中使用它。 Link to Ascii values

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-12
        • 1970-01-01
        • 1970-01-01
        • 2018-05-23
        • 1970-01-01
        • 1970-01-01
        • 2020-04-02
        相关资源
        最近更新 更多