两人一组结对编程:html
1、实验过程:java
1.根据娄老师的博客,咱们先了解前缀表示法、中缀表示法和后缀表示法的概念:git
表达式Exp = S1 + OP + S2
(S1 ,S2是两个操做数,OP为运算符)有三种标识方法:算法
OP + S1 + S2
为前缀表示法
S1 + OP + S2
为中缀表示法
S1 + S2 + OP
为后缀表示法
例如:Exp = a * b + (c - d / e) * f
express
前缀式: + * a b * - c / d e f
中缀式: a * b + c - d / e * f
后缀式: a b * c d e / - f * +
编程
2.中缀表达式转化成后缀表达式的过程:数组
3.中缀表达式转化成后缀表达式代码实现:安全
import java.util.*; public class NewMyBC { String beforeExpression;//未转化的中缀表达式 String afterExpression = "";//转化后的后缀表达式 int left = 0;//定义左括号数 int right = 0;//定义右括号数 //判断符号的级别 public int judgeGrade(char chi) { int grade = 0; switch (chi) { //左括号是第一级 case '(': grade = 1; break; //+和-是第二级 case '+': case '-': grade = 2; break; //*和÷是第三级 case '*': case '÷': grade = 3; break; // "/"是第四级 case '/': grade = 4; break; //右括号是第五级 case ')': grade = 5; break; default: grade = 0; } return grade; } public void setBeforeExpression(String exp) { beforeExpression=exp; } public String transformWay() { Stack stack = new Stack();//新建一个空栈 int i = 0; char op; while (i < beforeExpression.length()) { op = beforeExpression.charAt(i);//op存放从中缀表达式中取到的元素 if (op >= '0' && op <= '9') { afterExpression = afterExpression + op;//若是是数字,则直接输出至后缀表达式 } else if (op == '+' || op == '-' || op == '*' || op == '÷') { afterExpression = afterExpression + ' ';//有运算符,在数字之间加空格 // 若是栈为空,则运算符直接入栈 if (stack.empty()) { stack.push(op); } //根据符号的级别判断操做 else if (judgeGrade(op) > judgeGrade((char) stack.peek())) { stack.push(op);//比栈顶级别高或相等,直接入栈 } else { afterExpression = afterExpression + String.valueOf(stack.pop()) + ' ';//不然直接输出 i--; } } else if (op == '(') { left++; stack.push(op);//左括号直接入栈 } else if (op == ')') { afterExpression += " "; right++; while ((char) stack.peek() != '(') {//右括号,出栈,直到左括号为止 afterExpression = afterExpression + String.valueOf(stack.pop()) + " "; } stack.pop(); } i++; } afterExpression += " "; while(!stack.empty()){ afterExpression=afterExpression+String.valueOf(stack.pop())+" "; } if (left != right) { System.out.println("括号有误"); System.exit(0); } return afterExpression; } }
4.后缀表达式求值的步骤:服务器
5.求值代码:网络
import java.util.Stack; 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) { int op1, op2, result = 0; String token; StringTokenizer tokenizer = new StringTokenizer(expr);//划分表达式 while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken();//将算数表达式分解的 if (isOperator(token))//见下方isOperateor方法,当是运算符的时候进入if语句 { op2 = (stack.pop()).intValue(); op1 = (stack.pop()).intValue();//弹出最上面两个操做数 result = evalSingleOp(token.charAt(0), op1, op2);//见下方evaSingleOp方法 stack.push(new Integer(result));//将计算结果压栈 } else{ stack.push(new Integer(Integer.parseInt(token)));//操做数入栈 } } return result;//输出结果 } private boolean isOperator(String token)//判断是否为运算符,注意用equal语句比较字符串 { 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; } return result; } }
6.测试代码以下:
import java.util.Scanner; public class MyDCTest { public static void main(String[] args) { String expression, again; int result; try { Scanner in = new Scanner(System.in); do { MyDC evaluator = new MyDC(); System.out.println("Enter a valid postfix expression: "); expression = in.nextLine(); result = evaluator.evaluate(expression); System.out.println(); System.out.println("That expression equals " + result); System.out.print("Evaluate another expression [Y/N]? "); again = in.nextLine(); System.out.println(); } while (again.equalsIgnoreCase("y")); } catch (Exception IOException) { System.out.println("Input exception reported"); } } }
2、实验截图:
3、码云连接
结对编程:1人负责客户端,一人负责服务器
1、实验过程:
1.通过与搭档协商,我负责客户端(Client.java)部分,搭档负责服务端(Server.java)部分。
2.客户端部分的代码以下:
import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.*; import java.net.*; import java.util.*; public class Client { public static void main(String[] args) { Socket socket;//套接字对象 DataInputStream in=null;//输入流 DataOutputStream out=null;//输出流 //中缀表达式的输入 String str; Scanner scanner=new Scanner(System.in); System.out.println("请输入中缀表达式:"); str=scanner.nextLine(); try { socket=new Socket("localhost",5203); in=new DataInputStream(socket.getInputStream()); out=new DataOutputStream(socket.getOutputStream()); out.writeUTF(str); String s=in.readUTF(); System.out.println("结果为:\n"+s); } catch (Exception e) { System.out.println("服务器已断开"+e); } } }
2、实验截图:
3、码云连接
加密结对编程:1人负责客户端,一人负责服务器
1、实验过程:
1.我负责客户端,负责编写Client.java
.
2.根据娄老师的密码学算法博客,我和搭档所共同完成的DES算法代码以下:
import java.io.*; import javax.crypto.*; public class Skey_DES{ public static void main(String args[]) throws Exception{ KeyGenerator kg=KeyGenerator.getInstance("DESede"); kg.init(168); SecretKey k=kg.generateKey( ); FileOutputStream f=new FileOutputStream("key1.dat"); ObjectOutputStream b=new ObjectOutputStream(f); b.writeObject(k); } }
3.Client.java代码以下:
在以前的代码上,增长以下代码:
import java.io.*; import java.net.*; import java.util.Scanner; public class Client { public static void main(String[] args) { String mess; Scanner scanner=new Scanner(System.in); System.out.println("请输入问题"); mess=scanner.nextLine(); String key=""; int n=-1; byte [] a=new byte[128]; try{ File f=new File("key1.dat"); InputStream in = new FileInputStream(f); while((n=in.read(a,0,100))!=-1) { key=key+new String (a,0,n); } in.close(); } catch(IOException e) { System.out.println("File read Error"+e); } System.out.println("客户端提出的问题为:"+mess); NewMyBC mybc=new NewMyBC(); String str; mybc.setBeforeExpression(mess); str=mybc.transformWay(); String mi=EncryptDecrypt.AESEncode(key,str); System.out.println("客户端加密后密文为:"+mi); Socket socket; DataInputStream in=null; DataOutputStream out=null; try{ socket=new Socket("localhost",5006); in=new DataInputStream(socket.getInputStream()); out=new DataOutputStream(socket.getOutputStream()); BufferedReader in1=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter writer=new PrintWriter(socket.getOutputStream()); out.writeUTF(mi); String s=in.readUTF(); //in读取信息,堵塞状态 System.out.println("客户收到服务器的回答为:"+s); Thread.sleep(500); } catch(Exception e) { System.out.println("服务器已断开"+e); } } }
2、实验截图:
3、码云连接
密钥分发结对编程:1人负责客户端,一人负责服务器
1、实验过程:
1.我负责客户端,搭档负责服务器端。
2.根据娄老师的密码学算法博客,我和搭档共同完成的DES算法代码以下:
import java.security.PublicKey; import java.security.PrivateKey; import java.io.*; import javax.crypto.KeyAgreement; import javax.crypto.spec.*; public class KeyAgree{ public static void main(String args[ ]) throws Exception{ // 读取对方的DH公钥 File file=new File("Ckey.dat"); FileInputStream f1=new FileInputStream("Apub.dat"); ObjectInputStream b1=new ObjectInputStream(f1); PublicKey pbk=(PublicKey)b1.readObject( ); //读取本身的DH私钥 FileInputStream f2=new FileInputStream("Bpri.dat"); ObjectInputStream b2=new ObjectInputStream(f2); PrivateKey prk=(PrivateKey)b2.readObject( ); // 执行密钥协定 KeyAgreement ka=KeyAgreement.getInstance("DH"); ka.init(prk); ka.doPhase(pbk,true); //生成共享信息 byte[ ] sb=ka.generateSecret(); for(int i=0;i<sb.length;i++){ System.out.print(sb[i]+","); } OutputStream out=new FileOutputStream(file); out.write(sb); out.close(); SecretKeySpec k=new SecretKeySpec(sb,"AES"); } }
public class Dapart { String dapartstring(String str){ String s=""; char c[]=str.toCharArray(); for(int i=0;i<c.length;i++){ s=s+c[i]+" "; } return s; } }
部分代码,具体代码见码云连接
3.客户端的代码在实验二的基础上增长以下代码:
import java.io.*; import java.net.*; import java.util.Scanner; public class Client { public static void main(String[] args)throws IOException{ String key=""; int n=-1; byte [] a=new byte[128]; try{ File f=new File("Ckey.dat"); InputStream in = new FileInputStream(f); while((n=in.read(a,0,100))!=-1) { key=key+new String (a,0,n); } in.close(); } catch(IOException e) { System.out.println("File read Error"+e); } String mess; Scanner scanner=new Scanner(System.in); System.out.println("请输入问题:"); mess=scanner.nextLine(); NewMyBC mybc=new NewMyBC(); String str; mybc.setBeforeExpression(mess); str=mybc.transformWay(); String m=EncryptDecrypt.AESEncode(key, str); System.out.println("客户加密以后的密文为:"+m); Socket mysocket; DataInputStream in=null; DataOutputStream out=null; try{ mysocket=new Socket("localhost",6006); in=new DataInputStream(mysocket.getInputStream()); out=new DataOutputStream(mysocket.getOutputStream()); out.writeUTF(m); String s=in.readUTF(); //in读取信息,堵塞状态 System.out.println("客户收到服务器的回答为:"+s); Thread.sleep(500); } catch(Exception e) { System.out.println("服务器已断开"+e); } } }
2、实验截图:
3、码云连接
实验五 网络编程与安全-5
完整性校验结对编程:1人负责客户端,一人负责服务器
1、实验过程:
1.我负责客户端,搭档负责服务器端。
2.根据娄老师的密码学算法博客,我和搭档共同完成的算法代码以下:
import java.security.*; public class DigestPass{ static String md5(String str) throws Exception{ MessageDigest m=MessageDigest.getInstance("MD5"); m.update(str.getBytes("UTF8")); byte s[ ]=m.digest( ); String result=""; for (int i=0; i<s.length; i++){ result+=Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6); } return result; } }
3.客户端代码以下:
就以前实验二的代码添加以下代码:
import java.net.*; import java.util.Scanner; public class Client { public static void main(String[] args) throws Exception { String key = ""; int n = -1; byte[] a = new byte[128]; try { File f = new File("Ckey.dat"); InputStream in = new FileInputStream(f); while ((n = in.read(a, 0, 100)) != -1) { key = key + new String(a, 0, n); } in.close(); } catch (IOException e) { System.out.println("File read Error" + e); } String mess; Scanner scanner = new Scanner(System.in); System.out.println("请输入问题为:"); mess = scanner.nextLine(); NewMyBC mybc = new NewMyBC(); String str; mybc.setBeforeExpression(mess); str = mybc.transformWay(); String md5 = DigestPass.md5(str); String mw = EncryptDecrypt.AESEncode(key, str); System.out.println("客户端提供的MD—5为:" + md5); System.out.println("客户加密以后的密文为:" + mw); Socket mysocket; DataInputStream in = null; DataOutputStream out = null; try { mysocket = new Socket("localhost", 2010); in = new DataInputStream(mysocket.getInputStream()); out = new DataOutputStream(mysocket.getOutputStream()); out.writeUTF(mw); out.writeUTF(md5); String answer = in.readUTF(); //in读取信息,堵塞状态 System.out.println("客户收到服务器的回答为:" + answer); Thread.sleep(500); } catch (Exception e) { System.out.println("服务器已断开" + e); } } }
部分代码,具体代码见码云连接
2、实验截图:
3、码云连接
Q:在运行代码时,提示Error:(1, 1) java: 非法字符: '\ufeff'
,该怎么作?
A:我百度了一下,找到了一篇博客,根据博客里的步骤,解决了问题。
步骤 | 耗时(h) | 百分比 |
---|---|---|
设计 | 2 | 20% |
代码实现 | 5 | 50% |
测试 | 5 | 20% |
分析总结 | 1 | 10% |
本次实验,我主要负责客户端代码,搭档负责服务器端代码,许多算法也是咱们根据娄老师的博客共同研究出来的。本次实验是最后一次实验了,本学期的确受Java折磨很多,可是仍是感谢娄老师给咱们提供了不少新的学习方法,相信之后Java会帮助咱们不少的。