结对实现中缀表达式转后缀表达式的功能 MyBC.java
结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.javajava
(
,入栈(
运算符在栈中时,它的优先级最低)
,则若干运算符所有出栈,直到出栈的是左括号,一对括号匹配import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.lang.String; import org.junit.Test; public class MyBC{ private static final Map<Character, Integer> basic = new HashMap<Character, Integer>(); static { basic.put('-', 1); basic.put('+', 1); basic.put('*', 2); basic.put('/', 2); basic.put('(', 0); } /** * 将 中缀表达式 转化为 后缀表达式 */ public static String toSuffix(String infix){ List<String> queue = new ArrayList<String>(); List<Character> stack = new ArrayList<Character>(); char[] charArr = infix.trim().toCharArray(); String standard = "*/+-()"; char ch = '&'; int len = 0; for (int i = 0; i < charArr.length; i++) { ch = charArr[i]; if(Character.isDigit(ch)) { len++; }else if(Character.isLetter(ch)) { len++; }else if(ch == '.'){ len++; }else if(Character.isSpaceChar(ch)) { if(len > 0) { queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i))); len = 0; } continue; }else if(standard.indexOf(ch) != -1) { if(len > 0) { queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i))); len = 0; } if(ch == '(') { stack.add(ch); continue; } if (!stack.isEmpty()) { int size = stack.size() - 1; boolean flag = false; while (size >= 0 && ch == ')' && stack.get(size) != '(') { queue.add(String.valueOf(stack.remove(size))); size--; flag = true; } while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) { queue.add(String.valueOf(stack.remove(size))); size--; } } if(ch != ')') { stack.add(ch); } else { stack.remove(stack.size() - 1); } } if(i == charArr.length - 1) { if(len > 0) { queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1))); } int size = stack.size() - 1; while (size >= 0) { queue.add(String.valueOf(stack.remove(size))); size--; } } } return queue.stream().collect(Collectors.joining(" ")); } }
import java.util.StringTokenizer; 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; /** * Sets up this evalutor by creating a new 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)) { //若是是运算符,调用isOperator op2 = (stack.pop()).intValue(); //从栈中弹出操做数2 op1 = (stack.pop()).intValue();//从栈中弹出操做数1 result = evalSingleOp(token.charAt(0), op1, op2); //根据运算符和两个操做数调用evalSingleOp计算result; stack.push(new Integer(result)); //计算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; } return result; } }
1人负责客户端,一人负责服务器
注意责任归宿,要会经过测试证实本身没有问题
基于Java Socket实现客户端/服务器功能,传输方式用TCP
客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式经过网络发送给服务器
服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果git
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class Service { public static void main(String[] args) throws IOException{ Service socketService = new Service(); socketService.oneServer(); } public void oneServer(){ try{ ServerSocket server=null; try{ server=new ServerSocket(5218); System.out.println("服务器启动成功!"); }catch(Exception e) { System.out.println("没有启动监听!"+e); } Socket socket=null; try{ socket=server.accept(); }catch(Exception e) { System.out.println("Error."+e); } String line,line2; BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter writer=new PrintWriter(socket.getOutputStream()); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); line2=in.readLine(); System.out.println("客户端:"+line2); MyDC f = new MyDC(); System.out.printf("%d",f.evaluate(line2)); writer.println(Integer.toString(f.evaluate(line2))); line=br.readLine(); while(!line.equals("end")){ writer.println(line); writer.flush(); System.out.println("服务器:"+Integer.toString(f.evaluate(in.readLine()))); System.out.println("客户端:"+in.readLine()); line=br.readLine(); } writer.close(); in.close(); socket.close(); server.close(); }catch(Exception e) { System.out.println("Error."+e); } } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.URL; public class Client { public static void main(String[] args) throws IOException { try { //Socket socket = new Socket("172.20.10.6", 5218); Socket socket = new Socket("172.20.10.6", 5218); System.out.println("客户端启动成功!"); System.out.println("请输入中缀表达式:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter write = new PrintWriter(socket.getOutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String expression; MyBC bc = new MyBC(); expression = br.readLine(); String input =new String(); input = bc.toSuffix("20-16/4+52-18*2"); //学号是:20165218(20)-(16)/4+(53)-(1)*2 while (!expression.equals("end")) { write.println(input); write.println(expression); write.flush(); System.out.println("转化的后缀表达式为:" + input); System.out.println("服务器返回值为:" + in.readLine()); expression = br.readLine(); } write.close(); in.close(); socket.close(); } catch (Exception e) { System.out.println("没法监听:" + e); } } }
加密结对编程:1人负责客户端,一人负责服务器算法
- 注意责任归宿,要会经过测试证实本身没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后经过网络把密文发送给服务器
- 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,能够用数组保存),而后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class AesEncodeUtil { //初始向量 public static final String VIPARA = "aabbccddeeffgghh"; //AES 为16bytes. DES 为8bytes //编码方式 public static final String bm = "UTF-8"; //私钥 private static final String ASE_KEY = "aabbccddeeffgghh"; //AES固定格式为128/192/256 bits.即:16/24/32bytes。DES固定格式为128bits,即8bytes。 /** * 加密 * * @param cleartext * @return */ public static String encrypt(String cleartext) { //加密方式: AES128(CBC/PKCS5Padding) + Base64, 私钥:aabbccddeeffgghh try { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes()); //两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES SecretKeySpec key = new SecretKeySpec(ASE_KEY.getBytes(), "AES"); //实例化加密类,参数为加密方式,要写全 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //PKCS5Padding比PKCS7Padding效率高,PKCS7Padding可支持IOS加解密 //初始化,此方法能够采用三种方式,按加密算法要求来添加。(1)无第三个参数(2)第三个参数为SecureRandom random = new SecureRandom();中random对象,随机数。(AES不可采用这种方法)(3)采用此代码中的IVParameterSpec cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv); //加密操做,返回加密后的字节数组,而后须要编码。主要编解码方式有Base64, HEX, UUE,7bit等等。此处看服务器须要什么编码方式 byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm)); return new BASE64Encoder().encode(encryptedData); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * 解密 * * @param encrypted * @return */ public static String decrypt(String encrypted) { try { byte[] byteMi = new BASE64Decoder().decodeBuffer(encrypted); IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes()); SecretKeySpec key = new SecretKeySpec( ASE_KEY.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //与加密时不一样MODE:Cipher.DECRYPT_MODE cipher.init(Cipher.DECRYPT_MODE, key, zeroIv); byte[] decryptedData = cipher.doFinal(byteMi); return new String(decryptedData, bm); } catch (Exception e) { e.printStackTrace(); return ""; } } }
import java.awt.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class ServiceAes { public static void main(String[] args) throws IOException{ Service socketService = new Service(); socketService.oneServer(); } public void oneServer(){ try{ ServerSocket server=null; try{ server=new ServerSocket(5223); System.out.println("服务器启动成功!"); }catch(Exception e) { System.out.println("没有启动监听!"+e); } Socket socket=null; try{ socket=server.accept(); }catch(Exception e) { System.out.println("Error."+e); } String line,line2; BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter writer=new PrintWriter(socket.getOutputStream()); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); line2=in.readLine(); System.out.println("客户端:"+line2); //建立对象aes,并调用 AesEncodeUtil 类中的解密方法 AesEncodeUtil aes = new AesEncodeUtil(); String line3 = new String(); line3 = aes.decrypt(line2); //调用 MyDC 类计算值 MyDC f = new MyDC(); System.out.printf("%d",f.evaluate(line3)); writer.println(Integer.toString(f.evaluate(line3))); line=br.readLine(); while(!line.equals("end")){ writer.println(line); writer.flush(); System.out.println("客户端:"+in.readLine()); System.out.println("服务器:"+Integer.toString(f.evaluate(in.readLine()))); line=br.readLine(); } writer.close(); in.close(); socket.close(); server.close(); }catch(Exception e) { System.out.println("Error."+e); } } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.URL; public class ClientAes { public static void main(String[] args) throws IOException { try { //Socket socket = new Socket("10.1.1.234", 5218); //Socket socket = new Socket("10.1.1.230", 5223); Socket socket = new Socket("172.20.10.2", 5223); System.out.println("客户端启动成功!"); System.out.println("请输入中缀表达式:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter write = new PrintWriter(socket.getOutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String expression; MyBC bc = new MyBC(); expression = br.readLine(); String input =new String(); String input2 = new String(); input = bc.toSuffix("1+(4*2)/2+5+4*3-4"); AesEncodeUtil aes = new AesEncodeUtil(); input2 = aes.encrypt(input); //建立对象aes,并调用 AesEncodeUtil 类中的加密方法 while (!expression.equals("end")) { write.println(input2); write.println(expression); write.flush(); System.out.println("aes加密的后缀表达式为:" ); System.out.println("服务器返回值为:" + in.readLine()); expression = br.readLine(); } write.close(); in.close(); socket.close(); } catch (Exception e) { System.out.println("没法监听:" + e); } } }
密钥分发结对编程:1人负责客户端,一人负责服务器express
- 注意责任归宿,要会经过测试证实本身没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密经过网络把密文发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,而后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
public class Key_DH{ private static final byte skip1024ModulusBytes[] = { (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 }; // The SKIP 1024 bit modulus private static final BigInteger skip1024Modulus = new BigInteger(1, skip1024ModulusBytes); // The base used with the SKIP 1024 bit modulus private static final BigInteger skip1024Base = BigInteger.valueOf(2); public static void main(String args[ ]) throws Exception{ DHParameterSpec DHP= new DHParameterSpec(skip1024Modulus,skip1024Base); KeyPairGenerator kpg= KeyPairGenerator.getInstance("DH"); kpg.initialize(DHP); KeyPair kp=kpg.genKeyPair(); PublicKey pbk=kp.getPublic(); PrivateKey prk=kp.getPrivate(); // 保存公钥 FileOutputStream f1=new FileOutputStream(args[0]); ObjectOutputStream b1=new ObjectOutputStream(f1); b1.writeObject(pbk); // 保存私钥 FileOutputStream f2=new FileOutputStream(args[1]); ObjectOutputStream b2=new ObjectOutputStream(f2); b2.writeObject(prk); } }