我无法为凯撒密码制作循环

时间:2014-11-13 20:39:59

标签: vb.net

对于学校的课程作业,我必须编写一个简单的凯撒密码,用户可以选择自己的班次(+ 1,+ 2等)。例如,如果用户选择+3(a - > d等)并在包含字母x,y或z的消息中键入,则这些字母必须环绕到字母表的开头,因此x变为a, y变为b,z变为c。我使用ASCII值来执行此操作。

另一个不太重要的问题是我为每个单选按钮使用了很多if-else语句来改变Caesar转换。如果可能的话,无论如何都要整理它并使其更有效率。 (例如,我为每个加密和解密按钮添加了三个if语句。)

我已将我目前的代码包含在下面。

Public Class
  Dim FnlValue As String = "" 
  Dim FnlChar As Char 
  Dim VariableChr As Single
  Dim caesar As Integer

  Private Sub encrypt_btn_Click(sender As Object, e As EventArgs) Handles encrypt_btn.Click
    FnlValue = "" 

    For VariableChrNo = 0 To (input.Text.Length - 1) 
      VariableChr = Asc(input.Text.Chars(VariableChrNo)) 
      FnlChar = Chr(VariableChr + caesar) 
      FnlValue = FnlValue + FnlChar 
    Next

    output.Text = FnlValue 

    If rad_2.Checked Then
      caesar = 2
    Else If

    If rad_3.Checked Then
      caesar = 3
    Else If

    If rad_4.Checked Then
      caesar = 4
    Else If
  End Sub

  Private Sub decrypt_btn_Click(sender As Object, e As EventArgs) Handles decrypt_btn.Click
    FnlValue = "" 

    For VariableChrNo = 0 To (output.Text.Length - 1)
      VariableChr = Asc(output.Text.Chars(VariableChrNo)) 
      FnlChar = Chr(VariableChr - caesar)
      FnlValue = FnlValue + FnlChar 
    Next

    input.Text = FnlValue 
  End Sub

  If rad_2.Checked Then
    caesar = -2
  Else If

  If rad_3.Checked Then
    caesar = -3
  Else If

    If rad_4.Checked Then
    caesar = -4
  Else If

End Class

2 个答案:

答案 0 :(得分:1)

计算机使用数字作为字符。当你在计算机上做凯撒密码时,你必须得到字符[“A”,“B”,“C”,“D”]的数字表示来自,例如,[0,1, 2,3] - > [1,2,3,0],如果你认为“A”为0,它看起来像[“D”,“A”,“B”,“C”] / em>的。所以你可以看到,大多数情况下你必须加1(在这种情况下)来获得输出值。但是,如果添加1到3,则得到4,这不是您想要的值之一。但!如果从1 + 3中减去4,则得到0,这就是你想要的。

ASCII使用65代表“A”,但你需要它为0才能使数学运算([0,1,2,3]事物)。因此,如果您获得“A”的ASCII值并减去65,则得到0.现在您可以使用数学方法处理。完成数学运算后,您必须添加起始编号(大写字母为65),以便字符编号与字符的表示形式对应。

您可能关注的ASCII字符集的另一部分是“a-z”(即小写字母)。你可以用它们做类似的事情,但是没有必要知道Asc(“a”)是97:你可以通过编写Asc("a")让计算机为你工作。

由于你足够敏锐地意识到你重复检查单选按钮可以完成整理一段代码(所谓的重构的一部分),我怀疑下面的代码可能会回答你的问题:

Function GetCaesarOffset() As Integer
    Dim offset As Integer = -1
    ' put your RadioButton names here in order of 1, 2, ...
    ' where RadioButton1 represents a shift of 2 (no shift is a bit pointless)
    Dim radButtons() As RadioButton = {RadioButton1, RadioButton2}

    ' iterate over the RadioButtons to find out which one is selected...
    For i As Integer = 0 To radButtons.Length - 1
        If radButtons(i).Checked Then
            ' we can return a value from the function right now
            Return i + 1
        End If
    Next

    Return -1 ' nothing was selected

End Function

Private Sub encrypt_btn_Click(sender As Object, e As EventArgs) Handles encrypt_btn.Click
    Dim caesarOffset As Integer = GetCaesarOffset()

    If caesarOffset = -1 Then
        ' the user has not chosen an offset value... tell them
        MessageBox.Show("Please choose a value for the offset.")
        ' now we don't need to continue in this Sub
        Exit Sub
    End If

    Dim txt As String = input.Text
    Dim alphabetLength As Integer = Asc("Z") - Asc("A") + 1 ' this will usually be 26

    Dim enciphered As String = ""

    For i As Integer = 0 To txt.Length - 1
        ' get the ASCII character code (a number)
        Dim c As Integer = Asc(txt(i))

        ' Check what range the ASCII code is in and take appropriate action

        If c >= Asc("a") AndAlso c <= Asc("z") Then
            ' Look at lowercase letters
            ' make it into a number in the range 0-25 by subtracting the
            ' number which corresponds to the letter "a"
            c = c - Asc("a")
            c = c + caesarOffset

            If c > alphabetLength Then
                ' oops! it has fallen off the end of the allowed values
                ' we can correct this by subtracting the length of the alphabet
                c -= alphabetLength
            End If

            c = c + Asc("a")
            enciphered &= Chr(c)

        ElseIf c >= Asc("A") AndAlso c <= Asc("Z") Then
            ' Look at uppercase letters
            c = c - Asc("A")
            ' we can use the Mod function instead of the If...Then
            c = (c + caesarOffset) Mod alphabetLength
            c = c + Asc("A")
            enciphered &= Chr(c)

            ' you could put another ElseIf here for numbers if you wanted to

        Else
            ' it wasn't an uppercase or lowercase character, so
            ' don't do anything to it.
            enciphered &= txt(i)
        End If

    Next

    output.Text = enciphered

End Sub

答案 1 :(得分:0)

另一种选择是使用单个控件(如Listbox)替换所有单选按钮控件,例如:

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    For i = 1 To 25   ' 25 = (total number of letters) - 1
        Me.ListBox1.Items.Add(i)
    Next
End Sub

所以要知道要跳多少个字母,你可以这样做:

Me.ListBox1.SelectedIndex + 1

例如:

Private Sub btn_Encrypt_Click(sender As System.Object, e As System.EventArgs) Handles btn_Encrypt.Click
    Me.TextBox2.Text = Me.Caesar(Me.TextBox1.Text, Me.ListBox1.SelectedIndex + 1)
End Sub

Private Sub btn_Decrypt_Click(sender As System.Object, e As System.EventArgs) Handles btn_Decrypt.Click
    Me.TextBox2.Text = Me.Caesar(Me.TextBox1.Text, Me.ListBox1.SelectedIndex + 1, Decrypt:=True)
End Sub

Private Function Caesar(ByVal Text As String, Optional ByVal jump As Integer = 1, Optional ByVal Decrypt As Boolean = False) As String

    Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder(Text)

    Dim Aa, Zz, ed As Integer   ' Aa = ASCII for 'a' or 'A'. Zz = ASCII for 'z' or 'Z'. ed = Encrypt or Decrypt ASCII.
    Dim ch As Char

    For i = 0 To Text.Length - 1
        ch = Me.TextBox1.Text(i)

        Select Case ch
            Case "A"c To "Z"c
                Aa = Asc("A"c)
                Zz = Asc("Z"c)

            Case "a"c To "z"c
                Aa = Asc("a"c)
                Zz = Asc("z"c)

            Case Else
                MsgBox("A char that is not a letter was found.", MsgBoxStyle.Critical, "Error")
                Return sb.ToString
        End Select

        If Decrypt Then
            ed = Asc(ch) - jump
            If ed < Aa Then
                ed += Zz - Aa + 1
            End If
        Else   ' Encrypt
            ed = Asc(ch) + jump
            If ed > Zz Then
                ed -= Zz - Aa + 1
            End If
        End If

        sb.Chars(i) = Chr(ed)
    Next

    Return sb.ToString
End Function