zoukankan      html  css  js  c++  java
  • 20165321 实验五 网络编程与安全

    任务1

    任务详情

    两人一组结对编程:
    0. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA

    1. 结对实现中缀表达式转后缀表达式的功能 MyBC.java
    2. 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
    3. 上传测试代码运行结果截图和码云链接

    代码

    由于myDC.java与myBC.java都不是主类,没有办法运行,所以只有上代码了。

    myDC.java

    import java.util.*;
    
    public class MyDC {
        /** constant for addition symbol */
        private final char ADD = '+';
        /** constant for subtraction symbol */
        private final char SUBTRACT = '-';
        /** constant for multiplication symbol */
        private final char MULTIPLY = '*';
        /** constant for division symbol */
        private final char DIVIDE = '/';
        /** the stack */
        private Stack<Integer> stack;
    
        public MyDC() {
            stack = new Stack<Integer>();
        }
    
        public int evaluate (String expr) {//expr是算数表达式
            int op1, op2, result = 0;
            String token;
            StringTokenizer tokenizer = new StringTokenizer (expr);
    
            while (tokenizer.hasMoreTokens()) {
                token = tokenizer.nextToken();//识别运算符
                //补充代码31-40行
                //如果是运算符,调用isOperator
                if (isOperator(token))//如果是运算符,调用isOperator
                {
                    char c[]=token.toCharArray();
                    op2=stack.pop();//从栈中弹出操作数2
                    op1=stack.pop();//从栈中弹出操作数1
                    result=evalSingleOp(c[0],op1,op2);//根据运算符和两个操作数调用evalSingleOp计算result;
                    stack.push(result);//计算result入栈;
                }
                else//如果是操作数
                {
                    stack.push(Integer.parseInt(token));//操作数入栈;
                }
            }
            return result;
        }
    
        private boolean isOperator (String token)
        {
            return ( token.equals("+") || token.equals("-") ||
                    token.equals("*") || token.equals("/") );
        }
    
        private int evalSingleOp (char operation, int op1, int op2) {
            int result = 0;
            switch (operation)
            {
                case ADD:
                    result = op1 + op2;
                    break;
                case SUBTRACT:
                    result = op1 - op2;
                    break;
                case MULTIPLY:
                    result = op1 * op2;
                    break;
                case DIVIDE:
                    result = op1 / op2;
                default:
    
            }
            return result;
        }
    }
    
    

    myBC.java

    import java.util.Stack;
    import java.util.StringTokenizer;
    
    public class MyBC {
        /** constant for addition symbol */
        private final char ADD = '+';
        /** constant for subtraction symbol */
        private final char SUBTRACT = '-';
        /** constant for multiplication symbol */
        private final char MULTIPLY = '*';
        /** constant for division symbol */
        private final char DIVIDE = '/';
        /** the stack */
        Stack<Integer> stack=new Stack<Integer>();;
    
        String expression;
        public void setExpression(String str) {
            expression=str;
        }
        public  String changedWay() {
            String changedExpression = "";
            Stack signStack = new Stack();// 操作符栈
            for (int i = 0; i < expression.length(); i++) {
                char c = expression.charAt(i);
                if (c >= '0' && c <= '9') {
                    changedExpression=changedExpression+c;
                }
                else if (c == '+' || c == '-' || c == '*' || c == '/') {
                    changedExpression=changedExpression+" ";//分隔数字
                    if (signStack.empty()) {
                        signStack.push(c);
                    }
                    else if (judgeValue(c) >= judgeValue((Character) signStack.peek())) {//优先级高于或等于,运算符号均进栈
                        signStack.push(c);
                    }
                    else {
                        changedExpression=changedExpression+(char)signStack.pop();
                        signStack.push(c);
                    }
                }
                else if (c=='(') {
                    signStack.push(c);
                }
                else if (c==')') {
                    while((char)signStack.peek()!='(') {
                        changedExpression=changedExpression+" "+signStack.pop();
                    }
                    signStack.pop();
                }
            }
            while(!signStack.empty()){
                changedExpression=changedExpression+" "+String.valueOf(signStack.pop());
            }
            return changedExpression;
        }
    
        private static int judgeValue(char c) {
            int value = 0;
            switch (c) {
                case '(':
                    value = 1;
                    break;
                case '+':
                case '-':
                    value = 2;
                    break;
                case '*':
                case '/':
                    value = 3;
                    break;
                case ')':
                    value = 4;
                    break;
                default:
                    value = 0;
                    break;
            }
            return value;
        }
        public int evaluate (String expr)
        {//后缀表达式的运算方法
            int op1, op2, result = 0;
            String token;
            StringTokenizer tokenizer = new StringTokenizer (expr);//使用StringTokenizer类分解String对象的字符序列,默认为空格符...
            //此时tokenizer为一个分析器
            while (tokenizer.hasMoreTokens()) {
                token = tokenizer.nextToken();
                if (isOperator(token))
                {
                    op2 = (stack.pop()).intValue();//出栈
                    op1 = (stack.pop()).intValue();//出栈
                    result = evalSingleOp (token.charAt(0), op1, op2);//String对象第一个字符转换为char类型的方法为:str.charAt(0)
                    stack.push (new Integer(result));//进栈
                }
                else {
                    stack.push(new Integer(Integer.parseInt(token)));//进栈
                }
            }
            return result;
        }
        private boolean isOperator (String token)
        {
            return ( token.equals("+") || token.equals("-") ||
                    token.equals("*") || token.equals("/") );
        }
        private int evalSingleOp (char operation, int op1, int op2)
        {
            int result = 0;
            switch (operation)
            {
                case ADD:
                    result = op1 + op2;
                    break;
                case SUBTRACT:
                    result = op1 - op2;
                    break;
                case MULTIPLY:
                    result = op1 * op2;
                    break;
                case DIVIDE:
                    result = op1 / op2;
                default:
                    break;
            }
            return result;
        }
    }
    
    

    任务2

    任务详情

    结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
    3. 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    4. 客户端显示服务器发送过来的结果
    5. 上传测试结果截图和码云链接

    我完成的是服务器部分

    运行截图(服务器部分)

    客户端部分的截图在我的结对搭档的博客里面

    代码

    Server_2.java

    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class Server_2 {
        public static void main(String[] args) {
            final int port=5353;
            ServerSocket Server_2forClient_2=null;
            Socket SocketOnServer_2=null;
            DataOutputStream Server_2out=null;
            DataInputStream Server_2in=null;
            try {
                Server_2forClient_2=new ServerSocket(port);
            }
            catch (IOException e1) {
                System.out.println(e1);
                //e1.printStackTrace();
            }
            try {
                System.out.println("等待客户端呼叫……");
                SocketOnServer_2=Server_2forClient_2.accept();
                Server_2out=new DataOutputStream(SocketOnServer_2.getOutputStream());
                Server_2in=new DataInputStream(SocketOnServer_2.getInputStream());
                String s=Server_2in.readUTF();
                System.out.println("服务器接收到表达式:"+s);
                String expr;
                int result;
                MyBC mybc=new MyBC();
                mybc.setExpression(s);
                expr=mybc.changedWay();
                result=mybc.evaluate(expr);
                Server_2out.writeUTF("中缀表达式“"+s+"”转后缀表达式“"+expr+",运算结果为:"+result);
                //Thread.sleep(500);
            }
            catch (Exception e2) {
                System.out.println("客户端已断开"+e2);
            }
        }
    }
    
    

    Client_2.java

    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class Client_2 {
        public static void main(String[] args) {
            final int port=5353;
            final String host="172.30.4.50";
            Socket Client_2Socket;
            DataInputStream Client_2in=null;
            DataOutputStream Client_2out=null;
            String expr;
            Scanner scanner=new Scanner(System.in);
            System.out.println("请输入表达式:");
            expr=scanner.nextLine();
            try {
                Client_2Socket=new Socket(host,port);
                Client_2in=new DataInputStream(Client_2Socket.getInputStream());
                Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
                Client_2out.writeUTF(expr);
                String s=Client_2in.readUTF();
                System.out.println("服务器回复:
    "+s);
            }
            catch (Exception e) {
                System.out.println("服务器已断开"+e);
            }
        }
    }
    
    

    任务3

    任务详情

    加密结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
    3. 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    4. 客户端显示服务器发送过来的结果
    5. 上传测试结果截图和码云链接

    截图


    代码

    Server_3.java

    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class Server_3 {
        public static void main(String[] args) {
            ServerSocket Server_2forClient_2=null;
            Socket SocketOnServer_2=null;
            DataOutputStream Server_2out=null;
            DataInputStream Server_2in=null;
            try {
                Server_2forClient_2=new ServerSocket(5300);
            }
            catch (IOException e1) {
                System.out.println(e1);
                //e1.printStackTrace();
            }
            try {
                System.out.println("等待客户端呼叫……");
                SocketOnServer_2=Server_2forClient_2.accept();
                Server_2out=new DataOutputStream(SocketOnServer_2.getOutputStream());
                Server_2in=new DataInputStream(SocketOnServer_2.getInputStream());
                String CipherText=Server_2in.readUTF();
                String expr;
                byte []data=Base64.getDecoder().decode(CipherText);
                System.out.println("服务器接收到密文:"+data);
                expr=AES.DecryptionAES(data);
                int result;
                MyBC mybc=new MyBC();
                result=mybc.evaluate(expr);
                Server_2out.writeUTF("密文解密得后缀表达式:"+expr+",运算结果为:"+result);
                Thread.sleep(500);
            }
            catch (Exception e2) {
                System.out.println("客户端已断开"+e2);
            }
        }
    }
    
    

    Client_3.java

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.Socket;
    import java.util.*;
    
    public class Client_3 {
        public static void main(String[] args) {
            Socket Client_2Socket;
            DataInputStream Client_2in=null;
            DataOutputStream Client_2out=null;
            String expr=null;
            String str=null;
            String Ciphertext=null;
            Scanner scanner=new Scanner(System.in);
            System.out.println("请输入表达式:");
            str=scanner.nextLine();
            MyBC mybc=new MyBC();
            mybc.setExpression(str);
            expr=mybc.changedWay();
            try {
                AES.produceAESKey();//生成AES密钥
                byte[]cc= AES.EncryptionAES(expr);//需要传输的密文,数组形式传输。
                Ciphertext=Base64.getEncoder().encodeToString(cc);//将加密后的密文由byte[]转换为String类型
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            try {
                Client_2Socket=new Socket("10.1.1.175",5300);
                Client_2in=new DataInputStream(Client_2Socket.getInputStream());
                Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
                Client_2out.writeUTF(Ciphertext);
                String s=Client_2in.readUTF();
                System.out.println("服务器回复:
    "+s);
            }
            catch (Exception e) {
                System.out.println("服务器已断开"+e);
            }
        }
    }
    
    

    任务4

    任务详情

    密钥分发结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
    3. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    4. 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    5. 客户端显示服务器发送过来的结果
    6. 上传测试结果截图和码云链接

    代码

    Server_4.java

    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class Server_4 {
        public static void main(String[] args) {
            ServerSocket Server_2forClient_2=null;
            Socket SocketOnServer_2=null;
            DataOutputStream Server_2out=null;
            DataInputStream Server_2in=null;
            try {
                Server_2forClient_2=new ServerSocket(5200);
            }
            catch (IOException e1) {
                System.out.println(e1);
            }
            try {
                System.out.println("等待客户端呼叫……");
                SocketOnServer_2=Server_2forClient_2.accept();
                Server_2out=new DataOutputStream(SocketOnServer_2.getOutputStream());
                Server_2in=new DataInputStream(SocketOnServer_2.getInputStream());
                String Ciphertext=Server_2in.readUTF();//密文
                byte[] data= Base64.getDecoder().decode(Ciphertext);
                byte[] hh=AES_DH.DecryptionDES(data);
                Server_2out.writeUTF("接受到使用DH算法生成的共享密钥加密AES密钥生成的密文为:");
                for (int i=0;i<hh.length;i++) {
                    System.out.print(hh[i]+" ");
                }
                Thread.sleep(500);
            }
            catch (Exception e2) {
                System.out.println("客户端已断开"+e2);
            }
        }
    }
    

    Client_4.java

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.Socket;
    import java.util.*;
    
    public class Client_4 {
        public static void main(String[] args) {
            Socket Client_2Socket;
            DataInputStream Client_2in=null;
            DataOutputStream Client_2out=null;
            String expr=null;
            String str=null;
            String Ciphertext=null;
            System.out.println("传输使用DH算法生成的共享密钥加密AES密钥生成的密文");
            try {
                AES.produceAESKey();//生成AES密钥
                byte[]c= AES.changeWay();//AES密钥,数组形式传输。
    
                byte[]cc=AES_DH.EncryptionDES(c);//需要传输的使用DH算法生成的共享密钥加密AES密钥生成的密文,数组形式传输。
                Ciphertext = Base64.getEncoder().encodeToString(cc);//将加密后的密文由byte[]转换为String类型
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                Client_2Socket=new Socket("172.30.2.248",5200);
                Client_2in=new DataInputStream(Client_2Socket.getInputStream());
                Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
                Client_2out.writeUTF(Ciphertext);
                String s=Client_2in.readUTF();
                System.out.println("服务器回复:
    "+s);
            }
            catch (Exception e) {
                System.out.println("服务器已断开"+e);
            }
        }
    }
    

    AES_DH.java

    import javax.crypto.Cipher;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.security.Key;
    
    public class AES_DH {
        //AES加密,返回密文。
        public static byte[] EncryptionDES(byte[]data) throws Exception {
            FileInputStream f = new FileInputStream("A_Key_DESede_DH.dat");
            ObjectInputStream b = new ObjectInputStream(f);
            Key k = (Key) b.readObject();//从文件中获取密钥
            Cipher cp = Cipher.getInstance("AES");//创建密码器
            cp.init(Cipher.ENCRYPT_MODE, k);//初始化密码器,第一个参数指定密码器准备进行加密还是解密,第二个参数则传入加密或解密所使用的密钥。
            byte ctext[] = cp.doFinal(data);//执行Cipher对象的doFinal()方法,该方法的参数中传入待加密的明文,从而按照前面设置的算法与模式对明文加密。
            System.out.println("共享密钥加密完成!");
            //FileOutputStream f2 = new FileOutputStream("Ciphertext.txt");//将密文保存于Ciphertext.dat中。
            //f2.write(ctext);//处理加密结果
            return ctext;
        }
        //DESede解密,信息保存。
        public static byte[] DecryptionDES(byte[]data) throws Exception{
            FileInputStream f = new FileInputStream("A_Key_DESede_DH.dat");
            ObjectInputStream b = new ObjectInputStream(f);
            Key k = (Key) b.readObject();//从文件中获取密钥
            Cipher cp = Cipher.getInstance("AES");//创建密码器
            cp.init(Cipher.DECRYPT_MODE,k);
            byte ctext[]=cp.doFinal(data);
            //FileOutputStream ff=new FileOutputStream("Plaintext.txt");//将明文保存于Plaintext.dat中。
            //ff.write(ctext);
            System.out.println("共享密钥解密完成!");
            return ctext;
        }
    }
    
    

    任务5

    任务详情

    实验五 网络编程与安全-5
    完整性校验结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    3. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    4. 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    5. 客户端显示服务器发送过来的结果
    6. 上传测试结果截图和码云链接

    代码

    Server_5.java

    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class Server_5 {
        public static void main(String[] args) {
            ServerSocket Server_2forClient_2=null;
            Socket SocketOnServer_2=null;
            DataOutputStream Server_2out=null;
            DataInputStream Server_2in=null;
            try {
                Server_2forClient_2=new ServerSocket(5555);
            }
            catch (IOException e1) {
                System.out.println(e1);
                //e1.printStackTrace();
            }
            try {
                System.out.println("等待客户端呼叫……");
                SocketOnServer_2=Server_2forClient_2.accept();
                Server_2out=new DataOutputStream(SocketOnServer_2.getOutputStream());
                Server_2in=new DataInputStream(SocketOnServer_2.getInputStream());
                String expr=Server_2in.readUTF();
                System.out.println("服务器接收到表达式:"+expr);
                int result;
                MyBC mybc=new MyBC();
                //result=mybc.evaluate(expr);
                Server_2out.writeUTF("匹配成功");
                Thread.sleep(5000);
            }
            catch (Exception e2) {
                System.out.println("客户端已断开"+e2);
            }
        }
    }
    

    Client_5.java

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.Socket;
    import java.security.MessageDigest;
    import java.util.*;
    
    public class Client_5 {
        public static void main(String[] args) {
            Socket Client_2Socket;
            DataInputStream Client_2in=null;
            DataOutputStream Client_2out=null;
            String expr,str;
            Scanner scanner=new Scanner(System.in);
            System.out.println("请输入表达式:");
            str=scanner.nextLine();
            MyBC mybc=new MyBC();
            mybc.setExpression(str);
            expr=mybc.changedWay();
            try {
                MessageDigest m=MessageDigest.getInstance("MD5");//生成MessageDigest对象,使用静态方法
                m.update(expr.getBytes("UTF8"));//x为需要计算的字符串,update传入的参数是字节类型或字节类型数组,对于字符串,需要先使用getBytes( )方法生成字符串数组。
                byte ss[ ]=m.digest( );//计算的结果通过字节类型的数组返回。
                String result="";
                for (int i=0; i<ss.length; i++){
                    //处理计算结果
                    result+=Integer.toHexString((0x000000ff & ss[i]) |
                            0xffffff00).substring(6);
                }
                Client_2Socket=new Socket("172.30.2.248",5555);
                Client_2in=new DataInputStream(Client_2Socket.getInputStream());
                Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
                Client_2out.writeUTF(result);
                String s=Client_2in.readUTF();
                System.out.println("服务器回复:
    "+s);
            }
            catch (Exception e) {
                System.out.println("服务器已断开"+e);
            }
        }
    }
    
  • 相关阅读:
    SQL 判断字符包含在记录中出现了多少次
    JS 数据类型判断
    JS object转日期
    JS 日期转字符串
    Linux系统优化03-centos7网卡配置
    Linux系统安装02-centos7系统安装-分区及基本设置
    Linux系统安装01-centos7系统安装
    解决winserver2012R2安装VMware15(pro)问题
    Tomcat 如何设置Tomcat的标题,运行Tomcat显示为自己程序的命名
    IntelliJ Idea 常用快捷键列表
  • 原文地址:https://www.cnblogs.com/xpl20165321/p/9116230.html
Copyright © 2011-2022 走看看