【问题标题】:Vigenere Cipher(Java) [duplicate]Vigenere Cipher(Java)[重复]
【发布时间】:2016-05-21 18:22:32
【问题描述】:

我是 Java 的新手,我试图创建一个 vigenere 密码。这有点像凯撒移位,只有密钥多于一个字母,而且它是重复的,所以密码会更难破解。 我只完成了程序的加密部分,但当我意识到它运行不正常时我停止了。 我的意思是,它在某种程度上起作用,我认为,只有当我输入更长的字符串时,程序才会决定对我失败。它告诉我

线程“main”中的异常

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

嗯,我确实知道有一些“标准”方法可以在 Java 上制作 vigenere 密码,但我还没有了解他们正在使用的一些东西,所以我想知道你发现这个程序有什么问题。非常感谢!!!

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
    {
    }
    }

}

}

【问题讨论】:

    标签: java vigenere


    【解决方案1】:

    这是我整理的 Vigenere Cipher。

    我使用的是 GUI,但您可以将 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 '?';
                }
            }
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      alpha 中有 26 个字符,因此有效索引为 0-25。

      您检查是否j+l &gt; 26,并在需要时切换,但您应该检查是否j+l &gt; 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();
      }
      

      【讨论】:

        【解决方案3】:

        尝试不同的方法?这是我的,它只是创建一个新变量来保存加密消息并根据 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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-12-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多