目录
实验报告封面
课程:Java程序设计 班级:1752班 姓名:李得琛 学号:20175206
指导教师:娄嘉鹏 实验日期:2019年5月29日 实验序号:实验五 实验名称:网络编程与安全实验五 网络编程与安全-1
两人一组结对编程:
- 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
- 结对实现中缀表达式转后缀表达式的功能 MyBC.java
- 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
- 上传测试代码运行结果截图和码云链接
实验步骤
栈 (Stack)
是一种只允许在表尾插入和删除的线性表,有先进后出(FILO),后进先出(LIFO)的特点。允许插入和删除的一端称为栈顶(top)
,另一端称为栈底(bottom)
。
OP + S1 + S2
为前缀表示法S1 + OP + S2
为中缀表示法S1 + S2 + OP
为后缀表示法 在这里面我们主要讨论中缀转后缀 部分中转后代码: public String ChangeOrder() { Stack store = new Stack(); //创建一个存储字符的栈 for (int i = 0; i < C.length(); i++) { char op = C.charAt(i); //将索引值为i处的字符的值返回 if (op >= '0' && op <= '9') { End = End + op; } else if (op == '(') { store.push(op); } else if (op == '+' || op == '-' || op == '*' || op == '÷'|| op == '/') { End = End + " "; if (store.empty()) { store.push(op); } else if (compareValue(op) > compareValue((char) store.peek())) //比较运算符优先级 { store.push(op); } else { End = End + String.valueOf(store.pop()); i--; } } else if (op == ')') { while ((char) store.peek() != '(') { End = End + " " + String.valueOf(store.pop()); } store.pop(); } } while (!store.empty()) { End = End + " " + String.valueOf(store.pop()); } return End; }
计算器运算:
public class action { int numerator = 1 ; //分子 int denominator = 1; //分母 void setNumerator(int a) { //设置分子 int c=f(Math.abs(a),denominator); //计算最大公约数 numerator = a/c; denominator = denominator/c; if(numerator<0&&denominator<0) { numerator = -numerator; denominator = -denominator; } } void setDenominator(int b) { //设置分母 int c=f(numerator,Math.abs(b)); //计算最大公约数 numerator = numerator/c; denominator = b/c; if(numerator<0&&denominator<0) { numerator = -numerator; denominator = -denominator; } } int getNumerator() { return numerator; } int getDenominator() { return denominator; } int f(int a,int b) { //求a和b的最大公约数 if(a==0) { return 1; } if(a
后缀调用:
import java.util.StringTokenizer;import java.util.Stack;public class MyDC { String q; Stack stack; public MyDC() { stack = new Stack(); } void set(String question) { //输入后续排列的字符串 q = question; } public action get() { action op1 = new action(); action op2 = new action(); action result = new action(); result.setNumerator(0); StringTokenizer token = new StringTokenizer(q, " "); String temp; while (token.hasMoreTokens()) { temp = token.nextToken(); if (Isop(temp) == 1)//遇到操作符,弹出栈顶的两个数进行运算 { op2 = (action) stack.pop(); op1 = (action) stack.pop();//弹出最上面两个操作数 result = cal(temp.charAt(0), op1, op2);//根据运算符进行运算 stack.push(result);//将计算结果压栈 } else { action num = new action(); num.setNumerator(Integer.parseInt(temp)); stack.push(num);//操作数入栈 } } return result; } action cal(char op, action a, action b) { //对栈顶弹出的两个数进行运算 action c = new action(); switch (op) { case '+': c = a.add(b); break; case '-': c = a.sub(b); break; case '*': c = a.muti(b); break; case '÷': case '/': if(b.getNumerator()==0) { System.out.println("生成的算式计算时出现了分母为0的情况!"); System.exit(0); } else { c = a.div(b); break; } default: System.out.println("Wrong!"); } return c; } int Isop(String op) { //判断是不是运算符 if (op.equals("+") || op.equals("-") || op.equals("*") || op.equals("÷") || op.equals("/")) { return 1; } else { return 0; } }}
测试程序BCTEST.java
import java.util.*;public class BCTEST { public static void main(String[] args) { String question = ""; String question1 = ""; Scanner scanner = new Scanner(System.in); System.out.println("请输入题目:"); question = scanner.nextLine(); MyBC change = new MyBC(); change.ChangeString(question); question1 = change.ChangeOrder(); System.out.println(question1); MyDC getanswer = new MyDC(); getanswer.set(question1); action answer = getanswer.get(); int a = answer.getNumerator(); int b = answer.getDenominator(); float result = (float)a/b; System.out.println("结果为(保留两位小数):"); System.out.println(String.format("%.2f",result)); }}
实验截图
后缀:
中转后:
中转后带括号:
实验五 网络编程与安全-2
结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题!
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
- 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
实验步骤
在这里面先建立客户端和服务器之间的连接,鉴于是一台电脑同做服务器与客户端,那么IP地址填写本机客户端即可,否则将填写所在用户机IP地址
首先需要查明IP地址,本次用于作为客户端IP地址为192.168.1.239,如下面截图所示
因需要实现Java Socket
的功能,我们使用命令mysocket = new Socket();
来输入客户端IP以及其接口
客户端调用中转后mybc,服务器调用mydc
传输数据后即可看到结果,先启动服务器,在启动客户端。
代码部分如下:
调用部分:
try { socketOnServer = serverForClient.accept(); out = new DataOutputStream(socketOnServer.getOutputStream()); in = new DataInputStream(socketOnServer.getInputStream()); while(true) { question = in.readUTF(); // in读取信息,堵塞状态 System.out.println("服务器收到客户传递的后缀表达式为:" + question); MyDC getanswer = new MyDC(); getanswer.set(question); action answer = getanswer.get(); int a = answer.getNumerator(); int b = answer.getDenominator(); float result = (float) a / b; System.out.println("计算出的结果为"+String.format("%.2f",result)); out.writeUTF(String.format("%.2f",result)); Thread.sleep(500); } }
传输部分:
String IP = scanner.nextLine(); InetAddress address=InetAddress.getByName(IP); mysocket = new Socket(address, 2010); in=new DataInputStream(mysocket.getInputStream()); out=new DataOutputStream(mysocket.getOutputStream());
实验截图
查询IP:
服务器:
客户端:
实验五 网络编程与安全-3
加密结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
- 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
实验步骤
继承上述步骤,将输入的表达式进行加密传输 ,双方均可看到密钥及数据,本次使用DES进行加密
调用DES加密进行处理
DES加密格式代码:
SecretKeySpec k = new SecretKeySpec(kb, "DESede"); Cipher cp = Cipher.getInstance("DESede"); cp.init(Cipher.DECRYPT_MODE, k); String clength = in.readUTF(); byte ctext[] = new byte[Integer.parseInt(clength)]; for (int i = 0;i
即可看到结果
实验截图
服务器:
客户端:
实验五 网络编程与安全-4
密钥分发结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
实验步骤
继承实验三,使用DH算法将DES算法的密钥进行交换,服务器收到后解密,调用后缀进行计算,把结果返回客户端
在这里使用了DH算法
DH算法
1、初始化发送方的密钥2、初始化接受方的密钥3、密钥构建4、加密和解密
DH代码:
(byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7
生成一系列的dat
文件在这里是一堆乱码,就不在这里表达了。
实验截图
服务器:
客户端:
实验五 网络编程与安全-5
完整性校验结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
实验步骤
MD5:
MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。MD5算法具有以下特点:压缩性:任意长度的数据,算出的MD5值长度都是固定的。容易计算:从原数据计算出MD5值很容易。抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
使用MD5对DES进行加解密的过程,与DH过程类似
MD5代码:
public class MD5{ public static String MD5(String str) throws Exception{ String x=str; MessageDigest m=MessageDigest.getInstance("MD5"); m.update(x.getBytes("UTF8")); byte s[ ]=m.digest( ); String result=""; for (int i=0; i
实验截图
服务器:
客户端:
.
参考资料
代码链接
总结分析
步骤 | 耗时 | 百分比 |
---|---|---|
需求分析 | 10min | 12.5% |
设计 | 15min | 18.75% |
代码实现 | 30min | 37.5% |
测试 | 5min | 6.25% |
分析总结 | 20min | 25% |