2018-2019-2 20,175,327 experiments Five "network programming and security" test report

2018-2019-2 20,175,327 experiments Five "network programming and security" test report

Experimental Procedure:

A task

Experimental requirements: two pairs pair programming:

  • Reference http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
  • Junction function MyBC.java achieving infix expression transfer postfix expression
  • Pair achieve expression obtained from the above function implemented in the postfix expression functions, call MyDC.java
  • Upload test code and code run results screenshot cloud link

experiment procedure:

  • The operator between two operands written expression, referred to as "infix expression", as 1 + 2 * (3-4) +5. In infix expressions, operators have different priorities, the order of operations for changing the parentheses operator, so the process can not be directly evaluated in order from left to right.
  • The operator is written after the two operands expressions called "postfix" infix expressions as described above can be converted to postfix 1234-- + 5 * +. No postfix expression parentheses operator and no priority. Postfix expression evaluation process can be performed in strict sequence from left to right, in line with the law of demand value arithmetic unit.
  • Expression evaluation algorithm carried out in two steps: ① turn infix suffix; ② evaluation postfix expression.
  • Central conjugated found from postfix stack may be used, the following pseudo-code:
    • Establishment of a stack, storage operators, first stack is empty;
    • From left to right scan conjugated formula, if the operand encountered, direct output, and outputs two operands as a separator space;
    • If you encounter operator, compared with the top of the stack, the higher level than the top of the stack into the stack, or exit the top of the stack and output, then the output of a space as a separator;
    • If they are left parenthesis, push; If you encounter a right parenthesis, it has been de-stacked output, until retreated left parenthesis only.
    • When the stack becomes empty, the result is the output of the postfix expression.

The main experiment Code:
MyBC.java

import java.util.*;

public class MyBC {
    private Stack<String> stack;
    private List<String> list;

    private String message, Message = "";

    public MyBC() {
        stack = new Stack<String>();//用来暂时存放运算符的栈
        list = new ArrayList<String>();//用来暂时存放操作数及运算符的列表
    }

    public void conversion(String expr) {   //中缀转后缀
        String token;
        StringTokenizer tokenizer = new StringTokenizer(expr);

        while (tokenizer.hasMoreTokens()) {
            //当tokenizer有下一个值时,进行循环,并把值赋给token
            token = tokenizer.nextToken();

            if (token.equals("(")) {
                //如果是左括号,入栈
                stack.push(token);
            } else if (token.equals("+") || token.equals("-")) {
                //如果是“+”或“-”,继续判断栈是否为空
                if (!stack.empty()) {
                    //如果栈非空,判断栈顶元素是什么
                    if (stack.peek().equals("(")) {
                        //如果栈顶为“(”,运算符入栈
                        stack.push(token);
                    } else {
                        //否则先把栈顶元素移除,加到列表中,再将运算符入栈
                        list.add(stack.pop());
                        stack.push(token);
                    }
                } else {
                    //若栈为空,运算符入栈
                    stack.push(token);
                }
            } else if (token.equals("*") || token.equals("÷")) {
                //如果是“*”或“÷”,继续判断栈是否为空
                if (!stack.empty()) {
                    //如果栈非空,判断栈顶元素是什么
                    if (stack.peek().equals("*") || stack.peek().equals("÷")) {
                        //如果栈顶为“*”或“÷”,先把栈顶元素移除,加到列表中,再将运算符入栈
                        list.add(stack.pop());
                        stack.push(token);
                    } else {
                        //如果栈顶为其他,运算符直接入栈
                        stack.push(token);
                    }
                } else {
                    //如果栈为空,运算符直接入栈
                    stack.push(token);
                }
            } else if (token.equals(")")) {
                //如果遇到“)”,开始循环
                while (true) {
                    //先把栈顶元素移除并赋给A
                    String A = stack.pop();
                    if (!A.equals("(")) {
                        //如果A不为“(”,则加到列表
                        list.add(A);
                    } else {
                        //如果A为“(”,退出循环
                        break;
                    }
                }
            } else {
                //如果为操作数,进入列表
                list.add(token);
            }
        }
        while (!stack.empty()) {
            //将栈中元素取出,加到列表中,直到栈为空
            list.add(stack.pop());
        }
        ListIterator<String> li = list.listIterator();//返回此列表元素的列表迭代器(按适当顺序)。
        while (li.hasNext()) {
            //将迭代器中的元素依次取出,并加上空格作为分隔符
            Message += li.next() + " ";
            li.remove();
        }
        message = Message;
    }

    public String getMessage() {
        return message;
    }
}

MyDC.java

import java.util.*;

public class MyDC {
    private final char ADD = '+';
    private final char SUBTRACT = '-';
    private final char MUTIPLY = '*';
    private final char DIVIDE = '/';
    private Stack<Integer> stack;
    public MyDC(){
        stack = new Stack<Integer>();
    }
    public int evaluate(String expr){
        int op1,op2,result = 0;
        String token;
        StringTokenizer tokenizer = new StringTokenizer(expr);
        while(tokenizer.hasMoreTokens()){
            token = tokenizer.nextToken();
            if(isOperator(token)){
                op2 = (stack.pop().intValue());
                op1 = (stack.pop().intValue());
                result = evalSingleOp(token.charAt(0),op1,op2);
                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 MUTIPLY:
                result = op1*op2;
                break;
            case DIVIDE:
                result = op1/op2;
        }
        return result;
    }
}

Test code:
Calculator.java

import java.util.*;
public class Calculator {
    public static void main(String[] args) {
        String expression;
        int result;
        MyBC nts = new MyBC();
        MyDC value = new MyDC();
        System.out.println("Please input a nifix expression");
        Scanner in = new Scanner(System.in);
        expression = in.nextLine();
        nts.conversion(expression);
        System.out.println("The postfix expression is :"+nts.getMessage());
        result = value.evaluate(nts.getMessage());
        System.out.println("The result is :"+result);
    }
}

Screenshot experiment:

Task Two:

Experimental requirements

  • Pair programming: 1 person in charge of the client, a person in charge of server
  • Note that responsibility destination, we will pass the test to prove he did not question
  • Java Socket implement client / server-based functions, transmission using TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
  • 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果

实验原理
java.net.Socket』:

  • 套接字是一个网络连接的端点。在java中,使用java.net.Socket对象来表示一个套接字。
  • 要创建一个套接字,可以使用Socket的构造方法,如:public Socket(java.lang.String host, int port)。其中,host是远程机器名或IP地址,port是远程应用程序的端口号。
  • 一旦成功创建了Socket类的一个实例,就可以使用它发送或接收字节流。要发送字节流,必须先调用Socket类的getOutputStream方法来获取一个java.io.OutputStream对象。要向远程应用程序发送文本,通常要从返回的OutputStream对象构建一个java.io.PrintWriter对象。要接收来自连接的另一端的字节流,可以调用Socket类的getInputStream方法,它返回一个java.io.InputStream。
    『java.net.ServerSocket』:
  • ServerSocket是服务器套接字的一个实现。ServerSocket和Socket不同,服务器套接字的角色是,等待来自客户端的连接请求。一旦服务器套接字获得了一个连接请求,它就会创建一个Socket实例,以处理和客户端的通信。

实验截图:

任务三:

实验要求

  • 一人负责客户端,一人负责服务器
  • 注意责任归宿,要会通过测试证明自己没有问题
  • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
  • 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果

实验原理

  • 实现DES加密主要有以下几个步骤:
  • 对称密钥的生成和保存;
  • 使用对称密钥进行加密和解密;
  • 从文件中获取加密时使用的密钥,使用密钥进行解密。

实验截图:

任务四:

实验要求:

  • 密钥分发结对编程:1人负责客户端,一人负责服务器
  • 注意责任归宿,要会通过测试证明自己没有问题
  • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用DES或AES算法加密通过网络把密文发送给服务器
  • 客户端和服务器用DH算法进行DES或AES算法的密钥交换
  • 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果

实验过程

  • 两人先使用Key_DH类生成各自的DH公钥和私钥
  • 俩人使用对方的公钥和自己的私钥,用KeyAgree,生成共享密钥
  • 客户端使用共享密钥对原有的密钥进行加密,并把密文和加密后的密钥传输给服务器
  • 服务器先用共享密钥对客户端加密的密钥进行解密,再用解密后的密钥解密密文

实验截图:

任务五:

实验要求:

  • 完整性校验结对编程:
    • 注意责任归宿,要会通过测试证明自己没有问题
    • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    • 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    • 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    • 客户端显示服务器发送过来的结果

实验原理:
Java密码学算法中“Java摘要算法- MD5”部分的内容

实验截图:

码云链接: 代码

实验体会

此次实验的内容主要是是网络编程,同时结合密码学算法。在这次实验之前,虽然有学过Java网络编程理论内容,但真正自己动手编程时,发现并不太理解如何实现客户端和服务器,在和结对伙伴一起复习网络编程和密码学算法相关内容后,我们参考书上代码和Java 密码学算法,最终完成了实验,在这个过程中,我们复习了相关知识,也学到了很多信息安全的内容。

参考资料

Guess you like

Origin www.cnblogs.com/hollfull/p/10954233.html