2014-11-13 3 views
0

Для учебной задачи в школе мне нужно закодировать простой шифр Цезаря, где пользователь может выбрать свой собственный сдвиг (+1, +2 и т. Д.). Например, если пользователь выбирает +3 (a -> d и т. Д.) И вводит в сообщение, содержащее буквы x, y или z, эти буквы должны быть округлены до начала алфавита, так что x становится a, y становится b, z становится c. Для этого я использую значения ASCII.У меня возникли проблемы с созданием цикла для шифрования Цезаря

Еще одна важная проблема заключается в том, что я использовал довольно много операторов if-else для каждого переключателя, чтобы изменить сдвиг Цезаря. Если возможно, есть все равно, чтобы убрать это и сделать его более эффективным. (Я только что включил три примера для каждой кнопки шифрования и дешифрования для примеров.)

Я включил свой текущий код ниже.

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

Пока неясно, что вы просите. У вас проблема с алгоритмом? Если да, в чем проблема? Или вам просто нужны указатели на стиль кодирования? Я приветствую ваше желание научиться кодировать более идиоматические .NET, но это, вероятно, будет считаться не по теме. Форматирование кода помогает нам прочитать ваш вопрос, пожалуйста, используйте его. Кроме того, ваш код не компилируется - операторы if внизу не находятся внутри метода. Вот несколько советов по [как задать хорошие вопросы] (https://stackoverflow.com/help/how-to-ask) в StackOverflow. –

+1

Один из способов устранения операторов RadioButton If, чтобы сами кнопки сами устанавливали переменную 'caesar'. Используйте свои события CheckChanged. –

ответ

1

Компьютеры используют цифры для символов. Когда вы делаете шифр Цезаря на компьютере, вам нужно получить числовые представления символов [«A», «B», «C», «D»], чтобы перейти от, скажем, [0,1, 2,3] -> [1,2,3,0], который выглядит как «D», «A», «B», «C»] , если вы считаете «A» равным 0. Таким образом, вы можете увидеть, что в основном вы должны добавить 1 (в данном случае), чтобы получить выходное значение. Однако, если вы добавите 1 к 3, вы получите 4, что не является одним из значений, которые вы хотите. Но! если вы вычтите 4 из 1 + 3, тогда вы получите 0, что вам и нужно.

ASCII использует 65 для «A», но вам нужно, чтобы это было 0 для работы математики (вещь [0,1,2,3]). Итак, если вы получите значение ASCII для «A» и вычитаете 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 
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 
Смежные вопросы