20155117王震宇实验五网络编程与安全
网络编程与安全-2
两人一组结对编程:
-
- 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
-
- 结对实现中缀表达式转后缀表达式的功能 MyBC.java
-
- 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
-
- 上传测试代码运行结果截图和码云链接
- 实验代码
MyBC.java
package exp5;
import java.util.Stack;
public class MyBC {
public double GetResult(String infix) throws Exception {
StringBuffer suffix = new StringBuffer();
InfixToSuffix(infix, suffix);
return CalcSuffix(suffix.toString());
}
public String ExpressionOut(String infix) throws Exception{
StringBuffer suffix = new StringBuffer();
InfixToSuffix(infix, suffix);
return suffix.toString();
}
private void InfixToSuffix(String infix, StringBuffer suffix) throws Exception {
Stack<Character> s = new Stack<>();
int iLen = infix.length();
double num = 0;
for (int i = 0;i < iLen;i++) {
if (infix.charAt(i) == ' ')
continue;
else if (IsDigit(infix.charAt(i)))
suffix.append(infix.charAt(i));
else if (infix.charAt(i) == '(')
s.push(infix.charAt(i));
else if (infix.charAt(i) == ')') {
while (s.peek() != '(') {
suffix.append(s.peek());
s.pop();
}
s.pop();
}
else if (infix.charAt(i) == '+' || infix.charAt(i) == '-') {
suffix.append(' ');
if (s.empty() || s.peek() == '(')
s.push(infix.charAt(i));
else {
do {
suffix.append(s.peek());
s.pop();
} while (!s.empty() && s.peek() != '(');
s.push(infix.charAt(i));
}
}
else if (infix.charAt(i) == '*' || infix.charAt(i) == '/'){
suffix.append(' ');
if (GetPriority(s.peek(), infix.charAt(i)) == 1)
s.push(infix.charAt(i));
else {
while (!s.empty() && (GetPriority(s.peek(), infix.charAt(i)) < 1) && s.peek() != '(') {
suffix.append(s.peek());
s.pop();
}
s.push(infix.charAt(i));
}
}
}
while (!s.empty()) {
suffix.append(s.peek());
s.pop();
}
}
private double CalcSuffix(String suffix) {
Stack<Double> s = new Stack<>();
int iLen = suffix.length();
double result = 0;
StringBuffer temp = new StringBuffer();
for (int i = 0;i < iLen;i++) {
if (IsDigit(suffix.charAt(i)))
temp.append(suffix.charAt(i));
else if (suffix.charAt(i) == ' ') {
if (temp.length() > 0) {
s.push(Double.valueOf(temp.toString()));
temp.setLength(0);
}
}
else if (IsOperator(suffix.charAt(i))) {
if (temp.length() > 0){
s.push(Double.valueOf(temp.toString()));
temp.setLength(0);
}
double op1 = s.peek();
s.pop();
double op2 = s.peek();
s.pop();
result = Calc(op1, op2, suffix.charAt(i));
s.push( result);
}
}
return s.peek();
}
private boolean IsDigit(char ch) {
return (ch >= '0' && ch <= '9') || ch == '.' ? true : false;
}
private boolean IsOperator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/' ? true : false;
}
private int GetPriority(char op1, char op2) throws Exception {
if ((op1 == '+' || op1 == '-') && (op2 == '-' || op2 == '+'))
return 0;
else if (op1 == op2)
return 0;
else if ((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/'))
return 1;
else if ((op1 == '*' || op1 == '/') && (op2 == '-' || op2 == '+'))
return -1;
else if ((op1 == '*' || op1 == '/') && (op2 == '*' || op2 == '/') && op1 != op2)
return 0;
else
throw new Exception("Error");
}
private double Calc(double op1, double op2, char op) {
switch (op) {
case '+': return op2 + op1;
case '-': return op2 - op1;
case '*': return op2 * op1;
case '/': if (op1 != 0) return op2 / op1;
else return 0;
default: return 0;
}
}
}
MyBCTester.java
package exp5;
import java.util.Scanner;
public class MyBCTester {
public static void main (String[] args) {
String expression, again;
String ans;
double result;
try
{
Scanner in = new Scanner(System.in);
do
{
MyBC evaluator = new MyBC();
System.out.println ("Enter a expression: ");
expression = in.nextLine();
result = evaluator.GetResult(expression);
ans = evaluator.ExpressionOut(expression);
System.out.println();
System.out.println ("That expression equals " + result);
System.out.println();
System.out.println ("That expression " + ans);
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
结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
- 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
客户端
package exp5.exp5;
import java.net.*;
import java.beans.Expression;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.math.*;
public class Client2
{
public static void main(String srgs[]) throws Exception
{
try
{
// 1、创建客户端Socket,指定服务器地址和端口
Socket socket=new Socket("127.0.0.1",10000);
System.out.println("客户端启动成功");
// 2、获取输出流,向服务器端发送信息
// 向本机的10001端口发出客户请求
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 由系统标准输入设备构造BufferedReader对象
PrintWriter write = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
//3、获取输入流,并读取服务器端的响应信息
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
String readline, infix, expression;
readline = br.readLine(); // 从系统标准输入读入一字符串
MyBC theTrans = new MyBC(readline);
infix = theTrans.doTrans();
StringBuilder newInfix = new StringBuilder(infix.replace(" ",""));
for (int i = 1; i < infix.length()+(i+1)/2 ; i=i+2) {
newInfix.insert(i," ");
}
System.out.println("Postfix is " + newInfix);
expression=newInfix.toString();
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject();
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.ENCRYPT_MODE, k);
byte ptext[]=expression.getBytes("UTF-8");
byte ctext[]=cp.doFinal(ptext);
String Str=new String(ctext,"ISO-8859-1");
while (!readline.equals("end")) {
// 若从标准输入读入的字符串为 "end"则停止循环
write.println(Str);
// 将从系统标准输入读入的字符串输出到Server
write.flush();
// 刷新输出流,使Server马上收到该字符串
System.out.println("Client:" + Str);
// 在系统标准输出上打印读入的字符串
// System.out.println("MD5:38b8c2c1093dd0fec383a9d9ac940515");
// System.out.println("Server:" + in.readLine());
// 从Server读入一字符串,并打印到标准输出上
readline = br.readLine(); // 从系统标准输入读入一字符串
} // 继续循环
//4、关闭资源
write.close(); // 关闭Socket输出流
in.close(); // 关闭Socket输入流
socket.close(); // 关闭Socket
}
catch (Exception e)
{
System.out.println(e);//输出异常
}
finally
{
}
}
}
服务端
package exp5.exp5;
import java.net.*;
import java.io.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
import java.security.interfaces.*;
import java.math.*;
public class ComputerTCPServer2{
public static void main(String srgs[]) throws Exception
{
ServerSocket sc = null;
Socket socket=null;
try
{
MyDC evaluator = new MyDC();
sc= new ServerSocket(10000);//创建服务器套接字
System.out.println("端口号:" + sc.getLocalPort());
System.out.println("服务器已经启动...");
socket = sc.accept(); //等待客户端连接
System.out.println("已经建立连接");//获得网络输入流对象的引用
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获得网络输出流对象的引用
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
//使用服务器端RSA的私钥对DES的密钥进行解密
String aline2=in.readLine();
System.out.println("客户端发来的信息为:"+aline2);
// 获取密钥
byte[]ctext=aline2.getBytes("ISO-8859-1");
FileInputStream f2=new FileInputStream("keykb1.dat");
int num2=f2.available();
byte[ ] keykb=new byte[num2];
System.out.printf("\n");
f2.read(keykb);
SecretKeySpec k=new SecretKeySpec(keykb,"DESede");
// 解密
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.DECRYPT_MODE, k);
byte []ptext=cp.doFinal(ctext);
// 显示明文
String p=new String(ptext,"UTF8");
int ans = evaluator.evaluate(p);
System.out.println("result = "+ans);
} catch (Exception e) {
System.out.println(e);
}
}
//十六进制和十进制转换
public static byte[] parseHexStr2Byte(String hexStr)
{
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i< hexStr.length()/2; i++)
{
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1 ), 16);
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
DES加密
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject();
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.ENCRYPT_MODE, k);
byte ptext[]=expression.getBytes("UTF-8");
byte ctext[]=cp.doFinal(ptext);
String Str=new String(ctext,"ISO-8859-1");
DES解密
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.DECRYPT_MODE, k);
byte []ptext=cp.doFinal(ctext);