代码之家  ›  专栏  ›  技术社区  ›  Nikit Batale

课程结构

  •  3
  • Nikit Batale  · 技术社区  · 16 年前

    我应该写代码来模拟三种加密技术的工作:- Caesar Cipher Columnar Transposition 和 RSA

    public interface Encryption {
        public String encrypt(String key, String message);
    }
    

    分为两类,即。凯撒密码器和

    public class CaeserCipherEncryptor implements Encryption {
        private static final CaeserCipherEncryptor INSTANCE = new CaeserCipherEncryptor();
    
        private CaeserCipherEncryptor(){ }
    
        public static CaeserCipherEncryptor getInstance(){
            return INSTANCE;
        }
    
        public String encrypt(String key, String message) {
            int noOfShifts = Integer.parseInt(key);
            String cipherText = "";
            for(char c:message.toCharArray()){
                //to handle UpperCase and LowerCase alphabets
                if((Character.isUpperCase(c) && ((c+noOfShifts) > 90)) || (Character.isLowerCase(c) && ((c+noOfShifts) > 122)))
                    c = (char)((c + noOfShifts) - 26);
                else 
                    c = (char)(c + noOfShifts);
                cipherText += c;
            }
            return cipherText;
        }
    }
    

    ColumnArtTranspositionEncryptor实现它。

    import java.util.ArrayList;
    public class ColumnarTranspositionEncryptor implements Encryption {
        private static final ColumnarTranspositionEncryptor INSTANCE = new ColumnarTranspositionEncryptor();
    
        public static ColumnarTranspositionEncryptor getInstance(){
            return INSTANCE;
        }
    
        private ColumnarTranspositionEncryptor(){}
    
    
        @Override
        public String encrypt(String key, String message) {
            int rowLength = key.length();
            key.toUpperCase();
            ArrayList<Integer> finalOrder = new ArrayList<Integer>();
            for(int i=0;i<rowLength;i++){
                int rank=0;
                char c = key.charAt(i);
                for(int j=0;j<rowLength;j++){
                    if(c>key.charAt(j))
                        rank++;
                }
                finalOrder.add((rank+1));
            }
            ArrayList<String> rowsOfString=new ArrayList<String>();
            for(;message.length()>rowLength;message=message.substring(rowLength)){
                rowsOfString.add(message.substring(0, rowLength));
            }
            for(;message.length()>0 && message.length()<rowLength;){
                char c=65;
                message += (char)(c+new java.util.Random().nextInt(26));
            }
            rowsOfString.add(message);
            String cipherText = "";
            for(int i=1;i<=finalOrder.size();i++){
                int j=finalOrder.indexOf(i);
                for(String s:rowsOfString){
                    cipherText += s.charAt(j);
                }
            }
            System.out.println("Alphabetical order and columns:");
            for(int i:finalOrder)
                System.out.print(i + " ");
            System.out.println();
            System.out.println();
            for(String s:rowsOfString){
                for(int i=0;i<s.length();i++)
                    System.out.print(s.charAt(i) + " ");
                System.out.println();
            }
            // TODO Auto-generated method stub
            return cipherText;
        }
    }
    

    import java.util.ArrayList;
    import java.math.BigInteger;
    
    public class RSAUser {
        private int p,q,n,phiOfN, publicExponent, privateExponent;
    
        private static int gcd(int a, int b) {
            if (b == 0)
                return a;
            else
                return gcd(b, a % b);
        }
        public RSAUser(int p,int q){
            this.p = p;
            this.q = q;
            n = p * q;
            int phiOfN = (p - 1) * (q - 1);
            int min = Math.min(p, q);
            this.publicExponent = 2;
            ArrayList<Integer> x = new ArrayList<Integer>();
            for (; publicExponent < min - 1; publicExponent++) {
                if (RSAUser.gcd(publicExponent, phiOfN) == 1)
                    x.add(publicExponent);
            }
            this.publicExponent = x.get(new java.util.Random().nextInt(x.size()));
            privateExponent = phiOfN / publicExponent;
            for (int i = 1;; i++) {
                long product = phiOfN * i + 1;
                if (product % publicExponent == 0) {
                    privateExponent = (int)product / publicExponent;
                    break;
                }
            }
            System.out.println("Public Key:"+this.getPublicKey()+"\nPrivate Key:"+this.getPrivateKey());
        }
        //to print in the format "(n, publicExponent)"
        public String getPublicKey(){
            return "("+Integer.toString(n)+","+Integer.toString(publicExponent)+")";
        }
    
        public String getPrivateKey(){
            return "("+Integer.toString(n)+","+Integer.toString(privateExponent)+")";
        }
    }
    
    public class RSAEncryptor implements Encryption {
        private static RSAEncryptor instance = new RSAEncryptor();
    
        private RSAEncryptor(){
        }
    
        public static RSAEncryptor getInstance(){
            return instance;
        }
        @Override
        public String encrypt(String key, String message) {
            key.trim();
            String[] keys = key.split(",");
            String n = keys[0].substring(1).trim();
            String publicExponent = keys[1].trim();
            publicExponent = publicExponent.substring(0, publicExponent.length()-1);
            BigInteger m = new BigInteger(message);
            return m.pow(Integer.parseInt(publicExponent)).mod(new BigInteger(n)).toString(10);
        }
    
    }
    

    这种班级结构正确吗?这是正确的OO设计吗?提前谢谢你。

    1 回复  |  直到 16 年前
        1
  •  5
  •   hvgotcodes    16 年前

    一个简单的解决方案是不使用您所称的单例。每次需要加密时,只需创建加密实现的新实例。如果这样做,就可以在加密实例上存储所需的所有状态。这些实例只能使用一次;您可以防止它们在代码中被重用。

    或者,因为需要存储状态,所以可以创建一个EncryptionContext类,将其实例传递给encrypt方法。所有必要的状态都可以存储在这些上下文实例中,并且您可以对上下文进行错误检查,以确保在任何给定步骤中继续操作所需的所有信息都存在。如果您这样做,您可以重用加密实现实例。不过,您必须更改接口。。

    Strategy Pattern ,这很好。

    如果一个实现需要状态,那么它们也可能都需要状态。除非您想使用第三个选项,即为有状态加密算法创建单独的接口。但是,这并不吸引人,因为这是一个实现细节,不需要反映在接口中,接口的目的是表示 而不是 . 我还是会选择上面两个选项中的一个,要么是ok,要么是OO,IMHO。

    推荐文章