2016-05-21 6 views
0

Я довольно новичок в Java, и я попытался создать шифр vigenere. Это своего рода сдвиг Цезаря, только ключ - это нечто большее, чем одно письмо, и оно повторяется, поэтому шифр будет сложнее сломать. Я только закончил кодирующую часть программы, но я остановился, когда понял, что она не работает. Я имею в виду, он работает несколько, я думаю, только, когда я вхожу в более длинные строки, программа решает свалить на меня. Это говорит мнеVigenere Cipher (Java)

Исключения в потоке «главное»

java.lang.ArrayIndexOutOfBoundsException: 26 
at Cipher.encrypt(Cipher.java:30) 
at Cipher.main(Cipher.java:51) 

Гм, я знаю, что есть «стандартные» способы создания Vigenere шифров на Java, но я не узнал некоторые вещи, которые они имеют используя, поэтому я хотел бы знать, что вы считаете неправильным в этой программе. Огромное спасибо!!!

import java.util.Scanner; 


public class Cipher 
{ 

public static void encrypt (char[]alpha,String p, String key) 

{ 
String cipher=(""); 


for (int i=0; i<p.length(); i++) 


{ 


char c = p.charAt(i); 


int j=-1; 


int k=i%key.length(); 


int l=-1; 

     do // this one finds the letter character c corresponds to in the alphabet 
     { 
      j=j+1; 
     }while(c!=alpha[j]); 

     do// this one finds the letter that the key (or the letter used in the key) corresponds to in the alphabet 
     { 
      l=l+1; 
     }while(key.charAt(k)!=alpha[l]); 

     if (j+l>26)//if, say, the key is z and the character is z, then they would minus the shift by 26 so it stays inside the alphabet 
     { 
      c=alpha[j+l-26]; 
     } 
     else 
     { 
      c=alpha[j+l]; 
     } 

      cipher=cipher+c; 
     } 
     System.out.println(cipher.toUpperCase()); 
} 
public static void main(String[] args) 
{ 
    char[] alpha = "abcdefghijklmnopqrstuvwxyz".toCharArray(); 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Please enter a key for your vigenere cipher"); 
    String key= scan.nextLine().toLowerCase().replaceAll("[\\W]", ""); 
    System.out.println("Your key is "+key.toUpperCase()); 
    System.out.println("Would you like to encrypt or decrypt a message?"); 
    String ans=scan.nextLine(); 
    if (ans.equalsIgnoreCase("encrypt")) 
    { 
    System.out.println("Please enter your plaintext"); 
    String p= scan.nextLine().toLowerCase().replaceAll("[\\W]", ""); 
    System.out.println("Your plaintext is "+p); 
    encrypt(alpha,p,key); 
    } 
    else 
    { 
    } 
    } 

} 

}

ответ

0

Вот Vigenere Cipher, что я вместе взятые.

Vigenere Cipher

Я использовал графический интерфейс, но вы можете использовать шифровальные и uncipher методы класса TranslateTextListener с входом и выходом консоли.

Вот код:

package com.ggl.testing; 

import java.awt.Component; 
import java.awt.Container; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 

public class VigenèreCipher implements Runnable { 

    private static final Insets normalInsets = new Insets(10, 10, 0, 10); 
    private static final Insets finalInsets = new Insets(10, 10, 10, 10); 

    private JTextArea originalTextArea; 
    private JTextArea keyTextArea; 
    private JTextArea cipherTextArea; 
    private JTextArea uncipheredTextArea; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new VigenèreCipher()); 
    } 

    @Override 
    public void run() { 
     JFrame frame = new JFrame("Vigenère Cipher"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.add(createCipherPanel()); 

     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private JPanel createCipherPanel() { 
     JPanel panel = new JPanel(); 
     panel.setLayout(new GridBagLayout()); 

     int gridy = 0; 

     JLabel originalTextLabel = new JLabel("Original Text:"); 
     addComponent(panel, originalTextLabel, 0, gridy, 1, 1, normalInsets, 
       GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL); 

     originalTextArea = new JTextArea(5, 30); 
     originalTextArea.setLineWrap(true); 
     originalTextArea.setWrapStyleWord(true); 
     JScrollPane originalTextScrollPane = new JScrollPane(originalTextArea); 
     addComponent(panel, originalTextScrollPane, 1, gridy++, 1, 1, 
       normalInsets, GridBagConstraints.LINE_START, 
       GridBagConstraints.HORIZONTAL); 

     JLabel keyTextLabel = new JLabel("Key Text:"); 
     addComponent(panel, keyTextLabel, 0, gridy, 1, 1, normalInsets, 
       GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL); 

     keyTextArea = new JTextArea(5, 30); 
     keyTextArea.setLineWrap(true); 
     keyTextArea.setWrapStyleWord(true); 
     JScrollPane keyTextScrollPane = new JScrollPane(keyTextArea); 
     addComponent(panel, keyTextScrollPane, 1, gridy++, 1, 1, normalInsets, 
       GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL); 

     JLabel cipherTextLabel = new JLabel("Cipher Text:"); 
     addComponent(panel, cipherTextLabel, 0, gridy, 1, 1, finalInsets, 
       GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL); 

     cipherTextArea = new JTextArea(5, 30); 
     cipherTextArea.setLineWrap(true); 
     JScrollPane cipherTextScrollPane = new JScrollPane(cipherTextArea); 
     addComponent(panel, cipherTextScrollPane, 1, gridy++, 1, 1, 
       finalInsets, GridBagConstraints.LINE_START, 
       GridBagConstraints.HORIZONTAL); 

     JLabel uncipheredTextLabel = new JLabel("Unciphered Text:"); 
     addComponent(panel, uncipheredTextLabel, 0, gridy, 1, 1, finalInsets, 
       GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL); 

     uncipheredTextArea = new JTextArea(5, 30); 
     uncipheredTextArea.setLineWrap(true); 
     uncipheredTextArea.setWrapStyleWord(true); 
     JScrollPane uncipheredTextScrollPane = new JScrollPane(
       uncipheredTextArea); 
     addComponent(panel, uncipheredTextScrollPane, 1, gridy++, 1, 1, 
       finalInsets, GridBagConstraints.LINE_START, 
       GridBagConstraints.HORIZONTAL); 

     JButton submitButton = new JButton("Translate text"); 
     submitButton.addActionListener(new TranslateTextListener()); 
     addComponent(panel, submitButton, 0, gridy++, 2, 1, finalInsets, 
       GridBagConstraints.CENTER, GridBagConstraints.NONE); 

     return panel; 
    } 

    private void addComponent(Container container, Component component, 
      int gridx, int gridy, int gridwidth, int gridheight, Insets insets, 
      int anchor, int fill) { 
     GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, 
       gridwidth, gridheight, 1.0D, 1.0D, anchor, fill, insets, 0, 0); 
     container.add(component, gbc); 
    } 

    public class TranslateTextListener implements ActionListener { 

     private char[] cipherAlphabet; 

     private int lowerLimit; 
     private int upperLimit; 

     public TranslateTextListener() { 
      this.lowerLimit = 32; 
      this.upperLimit = 126; 
      this.cipherAlphabet = new char[upperLimit - lowerLimit + 1]; 
      // Grab all the ASCII characters between space and ~, inclusive 
      for (int i = lowerLimit; i <= upperLimit; i++) { 
       cipherAlphabet[i - lowerLimit] = (char) i; 
      } 
     } 

     @Override 
     public void actionPerformed(ActionEvent event) { 
      String text = originalTextArea.getText().trim(); 
      String key = keyTextArea.getText().trim(); 
      String cipher = cipherTextArea.getText().trim(); 
      String uncipher = ""; 

      if (!text.equals("") && !key.equals("")) { 
       cipher = cipher(text, key); 
      } 

      if (!key.equals("") && !cipher.equals("")) { 
       uncipher = uncipher(cipher, key); 
      } 

      cipherTextArea.setText(cipher); 
      uncipheredTextArea.setText(uncipher); 
     } 

     private String cipher(String text, String key) { 
      StringBuilder builder = new StringBuilder(text.length()); 
      int keyIndex = 0; 
      for (int i = 0; i < text.length(); i++) { 
       char c = text.charAt(i); 
       int pos = (int) c; 
       if (pos < lowerLimit || pos > upperLimit) { 
        builder.append(c); 
       } else { 
        char k = key.charAt(keyIndex); 
        pos = getCharacterPosition(c); 
        int pos2 = getCharacterPosition(k); 
        int sum = (pos + pos2) % cipherAlphabet.length; 
        builder.append(getCharacter(sum)); 
        keyIndex = ++keyIndex % key.length(); 
       } 
      } 
      return builder.toString(); 
     } 

     private String uncipher(String cipher, String key) { 
      StringBuilder builder = new StringBuilder(cipher.length()); 
      int keyIndex = 0; 
      for (int i = 0; i < cipher.length(); i++) { 
       char c = cipher.charAt(i); 
       int pos = (int) c; 
       if (pos < lowerLimit || pos > upperLimit) { 
        builder.append(c); 
       } else { 
        char k = key.charAt(keyIndex); 
        pos = getCharacterPosition(c); 
        int pos2 = getCharacterPosition(k); 
        int sum = pos - pos2; 
        while (sum < 0) { 
         sum += cipherAlphabet.length; 
        } 
        sum = sum % cipherAlphabet.length; 
        builder.append(getCharacter(sum)); 
        keyIndex = ++keyIndex % key.length(); 
       } 
      } 
      return builder.toString(); 
     } 

     private int getCharacterPosition(char c) { 
      for (int i = 0; i < cipherAlphabet.length; i++) { 
       if (c == cipherAlphabet[i]) { 
        return i; 
       } 
      } 

      return -1; 
     } 

     private char getCharacter(int index) { 
      if (index >= 0 && index < cipherAlphabet.length) { 
       return cipherAlphabet[index]; 
      } else { 
       return '?'; 
      } 
     } 

    } 
} 
0

Попробуйте другой подход? Вот мой, он просто создает новую переменную, которая будет хранить зашифрованное сообщение и сохраняет измененные символы там на основе значения ASCII. Мне все еще нужно добавлять пробелы, пока он шифрует только сообщения без каких-либо пробелов, но может быть до тех пор, пока я хочу.

public class vigenere { 
public static void main(String[] args) { 
    String encryptedMessage = ""; 
    String extended = ""; 
    int temp, counter; 

    String plain_text = JOptionPane.showInputDialog("Enter the text you wish to encrypt: "); 
    String keyword = JOptionPane.showInputDialog("Enter the keyword: "); 

    counter = plain_text.length()/keyword.length() + 3; 

    for (int i = 0; i < counter; i++){ 
     extended += keyword; 
    } 

    for (int j = 0; j < plain_text.length(); j++) { 


      if (plain_text.charAt(j) + ((extended.charAt(j) - 97)) > 122) { 
       temp = (int)(plain_text.charAt(j) + (extended.charAt(j) -123)); 
       encryptedMessage += (char)temp; 
      } else { 
       temp = (int)(plain_text.charAt(j) + (extended.charAt(j) - 97)); 
       encryptedMessage += (char)temp; 
      } 
     } 
    } 
    JOptionPane.showMessageDialog(null, encryptedMessage); 
} 

}

«Счетчик» для того, сколько раз мы должны продлить ключевое слово, чтобы соответствовать длине открытого текста, я положил +3 в конце концов, чтобы быть уверенным, но я думаю, +1 достаточно. Кроме того, я ОЧЕНЬ новичок в этом, поэтому этот код является таким же простым, как он может получить xD

0

В alpha содержится 26 символов, поэтому действительные индексы 0-25.

Вы проверяете, есть ли j+l > 26, и при необходимости сдвиньте, но вы должны проверить, j+l > 25.

еще лучше, не испытывает с if и обрабатывать различные случаи, просто сделать это безоговорочно:

c = alpha[(j + l) % 26]; 

Кроме того, вместо поиска для символа в алфавите, используйте вычитание:

j = c - 'a'; 

Я бы собрал все это следующим образом:

static String encrypt(String message, String key) { 
    StringBuilder buf = new StringBuilder(message.length()); 
    for (int idx = 0; idx < message.length(); ++idx) { 
    char p = message.charAt(idx); 
    int j = p - 'a'; 
    char k = key.charAt(i % key.length()); 
    int l = k - 'a'; 
    char c = (char) ('a' + ((j + l) % 26)); 
    buf.append(c); 
    } 
    return buf.toString(); 
} 
Смежные вопросы