对于学校的课程作业,我必须编写一个简单的凯撒密码,用户可以选择自己的班次(+ 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
答案 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