20192307 2020-2021-1 《数据结构与面向对象程序设计》实验四报告
20192307 2020-2021-1-《数据结构与面向对象程序设计》实验四报告
- 课程:《数据结构与面向对象程序设计》
- 班级:1923班
- 姓名:常万里
- 学号:20192307
- 任课教师: 王志强
- 必修/选修:必修课
一、实验内容
- (一)Java Socket编程
1.学习蓝墨云上教材《Java和Android编程》“第16章 输入/输出 ”和“第22章 网络”,学习JavaSocket编程
2.结对编程。结对伙伴A编写客户端SocketClient.java,结对伙伴B编写服务器端。
3.截图加学号水印上传蓝墨云,代码push到码云,并撰写实验报告。- (二)Java和密码学
参考 http://www.cnblogs.com/rocedu/p/6683948.html
以结对的方式完成Java密码学相关内容的学习(帖子中所有代码和相关知识点需要学习)。提交学习成果码云链接和代表性成果截图,要有学号水印。- (三)编写有理数/复数计算器
结对编程,结对伙伴A编写有理数计算器。结对伙伴B编写复数计算器。截图加水印上传蓝墨云,代码push码云。- (四)远程有理数计算器
结对编程,结对伙伴A编程实现客户端,结果伙伴B实现服务器端。
客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴B(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端A,A收到结果后输出结果。截图加水印上传蓝墨云,代码push码云。- (五)远程复数计算器
结对编程,结对伙伴B编程实现客户端,结果伙伴A实现服务器端。
客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴A(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端B,B收到结果后输出结果。截图加水印上传蓝墨云,代码push码云。
二、实验过程及结果
(一)Java Socket编程
服务器端:
package ServerSocket;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 16:47
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import RSA.RSAEncrypt;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Server {
/*
* java.net.ServerSocket
* 运行在服务端的ServerSocket主要有两个作用
* 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的。
*
* 2:监听该端口,这样一旦一个客户端通过该端口尝试建立连接时,ServerSocket就会自动实例化
* 一个Socket,那么通过这个Socket就可以与客户端对等并进行数据交互了。
*/
private ServerSocket server;
public Server() {
try {
/*
* 实例化ServerSocket的同时要向系统
* 申请服务端口,客户端就是通过这个端
* 口与服务端建立连接的。
*/
System.out.println("正在启动服务端...");
server = new ServerSocket(8080);
System.out.println("服务端启动完毕!");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
public void start() {
try {
/*
* Socket accept()
* ServerSocket的accept方法是一个阻塞
* 方法,调用后会一直等待,直到一个客户端
* 建立连接为止,此时该方法会返回一个Socket
* 实例,通过这个Socket就可以与刚连接上的
* 客户端进行数据交互了。
* 多次调用accept可以等待不同客户端的连接
*/
RSAEncrypt.genKeyPair();
while (true) {
System.out.println("等待客户端连接...");
Socket socket = server.accept();
System.out.println("一个客户端连接了!");
/*
* 通过Socket获取输入流,可以读取到远端
* 计算机发送过来的字节。
*/
InputStream in = socket.getInputStream();
InputStreamReader isr
= new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader br
= new BufferedReader(isr);
Scanner scanner = new Scanner(System.in);
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw, true);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("客户端说:" + line);
String kEY2 = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALwUtw1lbfBwY8WXmPZUBOvkvf3f/hnZFXQJqm1uCjYL8+1NjIDBCtTaEvvQpN/BBMq7jClU0QnrRkiQq8F4S68mmp8COUCTq7Bfh0W7KqTuwxk2JgDbPip0/6AfufgTN1kB1ADGSvvQW0nb9ZbgAa6ipOaDX+Gq/g22/fMqNCARAgMBAAECgYEAr8Q0JaLKkU6XDwtTebCfQMxt+Zmg4AsNj3mQ+d9CT6vv867rRVAijTSXVRlxW2II1mVa4S1QhZKIBjydJpsDLjlB8XnuzF6gazusXJCYW3/vFHNuQgaovOQ1EBI2Hta6k8yFzyl37rqIAOLQYpQs1VemlpHQ6nlWe0fCqvyotyECQQD3FZwENyP5w5sST7wxxcIyJAv2iO01CxovUjHcyxjNgmT3zy9q8VY5dWlomxp3N5TbZoq+RN+IKQh9yexiz8GFAkEAwt4Su+6KUzahvqS5AfIl46inzRDLXf5IOEsxwbuQaVJdYkQJD4xFxK5e3xJV734DMDNFxhgW7xtBmtHsA4qkHQJBAK8qPbHrWXDO0FfZ+SQb+8FKNsTva6LoHQchMUJDJXFEGMppskcRkrwnVbQYCVotKDWma4PaFdJUrLVoelHO0XUCQQCjhBdyTWMTGoe04qJACMJUe4R65fnQoHxXiHlzGIHAbxXfTDnSKyGsPalsRAWKVlI0kwGcjUBJWbS+RiJmgmLdAkB7MXkgJjxNLENiQbditwh15DyWIjocjhYaVvXj2QHWo+LXp7pEaEmLVTSJt4Q0lwzC2z4gbVp0AIfVQwDvSTp2\n";
String messageDe = RSAEncrypt.decrypt(line, kEY2);
System.out.println("解密后为:" + messageDe);
String line1 = scanner.nextLine();
String kEY1 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8FLcNZW3wcGPFl5j2VATr5L393/4Z2RV0Captbgo2C/PtTYyAwQrU2hL70KTfwQTKu4wpVNEJ60ZIkKvBeEuvJpqfAjlAk6uwX4dFuyqk7sMZNiYA2z4qdP+gH7n4EzdZAdQAxkr70FtJ2/WW4AGuoqTmg1/hqv4Ntv3zKjQgEQIDAQAB";
String messageEn = RSAEncrypt.encrypt(line1, kEY1);
pw.println(messageEn);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端:
package ServerSocket;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 16:47
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import NBE2.Complex;
import RSA.RSAEncrypt;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
public class Client {
/*
* java.net.Socket 套接字
* 封装了TCP协议的通讯细节,使得我们可以通过它
* 来与远端计算机建立TCP连接,并利用两个流的读写
* 完成数据交互。
*/
private Socket socket;
{
}
/**
* 构造方法,用来初始化客户端
*/
public Client() {
try {
/*
* Socket实例化是需要传入两个参数
* 参数1:服务端IP地址
* 参数2:服务端程序申请的端口
* 我们通过IP可以找到网络上的服务端计算机
* 通过端口可以连接到服务端计算机上运行的
* 服务端应用程序了。
* 注意:
* 实例化Socket的过程就是连接的过程,若
* 服务端没有响应这里会抛出异常。
*/
System.out.println("正在连接服务端...");
socket = new Socket("127.0.0.1", 8080);
System.out.println("与服务端成功建立连接!");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
/**
* 客户端开始工作的方法
*/
public void start() {
try {
Scanner scanner = new Scanner(System.in);
/*
* Socket提供的方法:
* OutputStream getOutputStream()
* 该方法获取的输出流是一个字节输出流
* 通过这个流写出的字节会通过网络发送
* 到远端计算机上(对于客户端这边而言,
* 远端计算机指的就是服务端了。)
*/
InputStream in = null;
try {
in = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
InputStreamReader isr
= null;
isr = new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader br
= new BufferedReader(isr);
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw, true);
RSAEncrypt.genKeyPair();
String line2 = null;
while (true) {
String line = scanner.nextLine();
String kEY1 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8FLcNZW3wcGPFl5j2VATr5L393/4Z2RV0Captbgo2C/PtTYyAwQrU2hL70KTfwQTKu4wpVNEJ60ZIkKvBeEuvJpqfAjlAk6uwX4dFuyqk7sMZNiYA2z4qdP+gH7n4EzdZAdQAxkr70FtJ2/WW4AGuoqTmg1/hqv4Ntv3zKjQgEQIDAQAB";
String messageEn = RSAEncrypt.encrypt(line, kEY1);
pw.println(messageEn);
try {
if (!((line2 = br.readLine()) != null)) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("服务端说:" + line2);
String kEY2 = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALwUtw1lbfBwY8WXmPZUBOvkvf3f/hnZFXQJqm1uCjYL8+1NjIDBCtTaEvvQpN/BBMq7jClU0QnrRkiQq8F4S68mmp8COUCTq7Bfh0W7KqTuwxk2JgDbPip0/6AfufgTN1kB1ADGSvvQW0nb9ZbgAa6ipOaDX+Gq/g22/fMqNCARAgMBAAECgYEAr8Q0JaLKkU6XDwtTebCfQMxt+Zmg4AsNj3mQ+d9CT6vv867rRVAijTSXVRlxW2II1mVa4S1QhZKIBjydJpsDLjlB8XnuzF6gazusXJCYW3/vFHNuQgaovOQ1EBI2Hta6k8yFzyl37rqIAOLQYpQs1VemlpHQ6nlWe0fCqvyotyECQQD3FZwENyP5w5sST7wxxcIyJAv2iO01CxovUjHcyxjNgmT3zy9q8VY5dWlomxp3N5TbZoq+RN+IKQh9yexiz8GFAkEAwt4Su+6KUzahvqS5AfIl46inzRDLXf5IOEsxwbuQaVJdYkQJD4xFxK5e3xJV734DMDNFxhgW7xtBmtHsA4qkHQJBAK8qPbHrWXDO0FfZ+SQb+8FKNsTva6LoHQchMUJDJXFEGMppskcRkrwnVbQYCVotKDWma4PaFdJUrLVoelHO0XUCQQCjhBdyTWMTGoe04qJACMJUe4R65fnQoHxXiHlzGIHAbxXfTDnSKyGsPalsRAWKVlI0kwGcjUBJWbS+RiJmgmLdAkB7MXkgJjxNLENiQbditwh15DyWIjocjhYaVvXj2QHWo+LXp7pEaEmLVTSJt4Q0lwzC2z4gbVp0AIfVQwDvSTp2\n";
String messageDe = null;
try {
messageDe = RSAEncrypt.decrypt(line2, kEY2);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("解密后为:" + messageDe);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果截图
(二)Java和密码学
Caesar密码
package Cryptography.Caesar;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/23
* \* Time: 21:44
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
public class Caesar {
public static void main(String[] args) throws Exception {
String s = args[0];
int key = Integer.parseInt(args[1]);
StringBuilder es = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 是小写字母
if (c >= 'a' && c <= 'z') {
c += key % 26;
//移动key%26位
if (c < 'a') {
c += 26;
//向左超界
}
if (c > 'z') {
c -= 26;
//向右超界
}
} else if (c >= 'A' && c <= 'Z')
// 是大写字母
{
c += key % 26;
if (c < 'A') {
c += 26;
}
if (c > 'Z') {
c -= 26;
}
}
es.append(c);
}
System.out.println(es);
}
}
DES算法
package Cryptography.DES_algorithm;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 18:20
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
public class SDec {
public static void main(String args[]) throws Exception {
// 获取密文
FileInputStream f = new FileInputStream("SEnc.dat");
int num = f.available();
byte[] ctext = new byte[num];
f.read(ctext);
// 获取密钥
FileInputStream f2 = new FileInputStream("keykb1.dat");
int num2 = f2.available();
byte[] keykb = new byte[num2];
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");
System.out.println(p);
}
}
package Cryptography.DES_algorithm;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 18:19
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
public class SEnc {
public static void main(String args[]) throws Exception {
String s = "Hello World!";
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[] = s.getBytes("UTF8");
for (int i = 0; i < ptext.length; i++) {
System.out.print(ptext[i] + ",");
}
System.out.println("");
byte ctext[] = cp.doFinal(ptext);
for (int i = 0; i < ctext.length; i++) {
System.out.print(ctext[i] + ",");
}
FileOutputStream f2 = new FileOutputStream("SEnc.dat");
f2.write(ctext);
}
}
package Cryptography.DES_algorithm;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 18:16
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
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);
}
}
package Cryptography.DES_algorithm;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 18:17
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
public class Skey_kb {
public static void main(String[] args) throws Exception {
FileInputStream f = new FileInputStream("key1.dat");
ObjectInputStream b = new ObjectInputStream(f);
Key k = (Key) b.readObject();
byte[] kb = k.getEncoded();
FileOutputStream f2 = new FileOutputStream("keykb1.dat");
f2.write(kb);
// 打印密钥编码中的内容
for (int i = 0; i < kb.length; i++) {
System.out.print(kb[i] + ",");
}
}
}
RSA算法
package Cryptography.RSA_algorithm;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 18:24
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateKey;
public class Dec_RSA{
public static void main(String args[]) throws Exception{
//读取密文
BufferedReader in=
new BufferedReader(new InputStreamReader(
new FileInputStream("Enc_RSA.dat")));
String ctext=in.readLine();
BigInteger c=new BigInteger(ctext);
//读取私钥
FileInputStream f=new FileInputStream("Skey_RSA_priv.dat");
ObjectInputStream b=new ObjectInputStream(f);
RSAPrivateKey prk=(RSAPrivateKey)b.readObject( );
BigInteger d=prk.getPrivateExponent();
//获取私钥参数及解密
BigInteger n=prk.getModulus();
System.out.println("d= "+d);
System.out.println("n= "+n);
BigInteger m=c.modPow(d,n);
//显示解密结果
System.out.println("m= " + m);
byte[] mt=m.toByteArray();
System.out.println("PlainText is ");
for(int i=0;i<mt.length;i++){
System.out.print((char) mt[i]);
}
}
}
package Cryptography.RSA_algorithm;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 18:30
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class DigestPass {
public static void main(String[] args) throws Exception {
String x = args[0];
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(x.getBytes(StandardCharsets.UTF_8));
byte[] s = m.digest();
StringBuilder result = new StringBuilder();
for (int i = 0; i < s.length; i++) {
result.append(Integer.toHexString((0x000000ff & s[i]) |
0xffffff00).substring(6));
}
System.out.println(result);
}
}
import java.io.*;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
public class Enc_RSA {
public static void main(String args[]) throws Exception {
String s = "Hello World!";
// 获取公钥及参数e,n
FileInputStream f = new FileInputStream("Skey_RSA_pub.dat");
ObjectInputStream b = new ObjectInputStream(f);
RSAPublicKey pbk = (RSAPublicKey) b.readObject();
BigInteger e = pbk.getPublicExponent();
BigInteger n = pbk.getModulus();
System.out.println("e= " + e);
System.out.println("n= " + n);
// 明文 m
byte ptext[] = s.getBytes("UTF8");
BigInteger m = new BigInteger(ptext);
// 计算密文c,打印
BigInteger c = m.modPow(e, n);
System.out.println("c= " + c);
// 保存密文
String cs = c.toString();
BufferedWriter out =
new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("Enc_RSA.dat")));
out.write(cs, 0, cs.length());
out.close();
}
}
public class Key_DH {
//三个静态变量的定义从
// C:\j2sdk-1_4_0-doc\docs\guide\security\jce\JCERefGuide.html
// 拷贝而来
// The 1024 bit Diffie-Hellman modulus values used by SKIP
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);
}
}
public class KeyAgree {
public static void main(String[] args) throws Exception {
// 读取对方的DH公钥
FileInputStream f1 = new FileInputStream(args[0]);
ObjectInputStream b1 = new ObjectInputStream(f1);
PublicKey pbk = (PublicKey) b1.readObject();
//读取自己的DH私钥
FileInputStream f2 = new FileInputStream(args[1]);
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 (byte b : sb) {
System.out.print(b + ",");
}
SecretKeySpec k = new SecretKeySpec(sb, "DESede");
}
}
public class Skey_RSA {
public static void main(String args[]) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
PublicKey pbkey = kp.getPublic();
PrivateKey prkey = kp.getPrivate();
// 保存公钥
FileOutputStream f1 = new FileOutputStream("Skey_RSA_pub.dat");
ObjectOutputStream b1 = new ObjectOutputStream(f1);
b1.writeObject(pbkey);
// 保存私钥
FileOutputStream f2 = new FileOutputStream("Skey_RSA_priv.dat");
ObjectOutputStream b2 = new ObjectOutputStream(f2);
b2.writeObject(prkey);
}
}
运行结果截图
(三)编写复数计算器
复数计算类:
package NBE2;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/10
* \* Time: 21:16
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
*
* @author Shape Of My Heart
*/
public class Complex implements Operation {
// 定义属性并生成getter,setter
double RealPart;
double ImagePart;
private Object o;
// 定义构造函数
public Complex() {
RealPart = 0;
ImagePart = 1;
}
public double getRealPart() {
return RealPart;
}
public void setRealPart(double realPart) {
RealPart = realPart;
}
public double getImagePart() {
return ImagePart;
}
public void setImagePart(double imagePart) {
ImagePart = imagePart;
}
public Complex(double R, double I) {
RealPart = R;
ImagePart = I;
}
//Override Object
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Complex)) {
return false;
}
Complex complex = (Complex) obj;
if (complex.RealPart != ((Complex) obj).RealPart) {
return false;
}
if (complex.ImagePart != ((Complex) obj).ImagePart) {
return false;
}
return true;
}
@Override
public String toString() {
String string = "";
if (ImagePart > 0) {
string = RealPart + "+" + ImagePart + "i";
}
if (ImagePart == 0) {
string = RealPart + "";
}
if (ImagePart < 0) {
string = RealPart + " " + ImagePart + "i";
}
return string;
}
// 定义公有方法:加减乘除
public Complex ComplexAdd(Complex a) {
double b, c;
b = RealPart + a.RealPart;
c = ImagePart + a.ImagePart;
System.out.println("(" + RealPart + "+" + ImagePart + "i) + (" + a.RealPart + "+" + a.ImagePart + ") = " + b + "+" + c + "i");
return new Complex(b, c);
}
public Complex ComplexSub(Complex a) {
double b, c;
b = RealPart - a.RealPart;
c = ImagePart - a.ImagePart;
System.out.println("(" + RealPart + "+" + ImagePart + "i) - (" + a.RealPart + "+" + a.ImagePart + ") = " + b + "+" + c + "i");
return new Complex(b, c);
}
public Complex ComplexMulti(Complex a) {
double b, c;
b = RealPart * a.RealPart - ImagePart * a.ImagePart;
c = ImagePart * a.RealPart + RealPart * a.ImagePart;
System.out.println("(" + RealPart + "i+" + ImagePart + "i) * (" + a.RealPart + "+" + a.ImagePart + "i) = " + b + "+" + c + "i");
return new Complex(b, c);
}
public Complex ComplexDiv(Complex a) {
if (a.RealPart == 0 || a.ImagePart == 0) {
System.out.println("被除数不能为0,错误");
return new Complex();
}
double b, c;
b = (RealPart * a.RealPart + ImagePart * a.ImagePart) / (Math.pow(a.RealPart, 2) + Math.pow(a.ImagePart, 2));
c = (ImagePart * a.RealPart - RealPart * a.ImagePart) / (Math.pow(a.RealPart, 2) + Math.pow(a.ImagePart, 2));
System.out.println("(" + RealPart + "i+" + ImagePart + "i) / (" + a.RealPart + "+" + a.ImagePart + "i) = " + b + "+" + c + "i");
return new Complex(b, c);
}
public int compareTo(Object o) {
Complex temp = (Complex) o;
if (temp.RealPart > this.RealPart) {
return 1;
} else {
return 0;
}
}
@Override
public int carry() {
return 0;
}
@Override
public int carry(Complex temp) {
if (temp.ImagePart > this.ImagePart) {
return 1;
} else {
return 0;
}
}
}
计算器代码
package NBE2;
import java.util.Scanner;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/24
* \* Time: 19:43
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
*
* @author Shape Of My Heart
*/
public class complexCalculator extends Complex {
public complexCalculator() {
}
public complexCalculator(double R, double I) {
super(R, I);
}
public static double Calculator(double x, double y, int z) {
return 0;
}
public static void main(String[] args) {
System.out.println(" Welcome!This is a simple calculator.\n");
for (; ; ) {
System.out.println("What kind of operations do you want?");
System.out.println("1.Addition");
System.out.println("2.Subtraction");
System.out.println("3.Multiplication");
System.out.println("4.Division");
System.out.println("5.Compare the size of the real part");
System.out.println("6.Compare the size of imaginary part");
System.out.println("7.Quit");
Scanner input = new Scanner(System.in);
int a = input.nextInt();
if (a < 1 || a > 7) {
System.out.println("error!please choose again");
}
if (a == 7) {
break;
}
System.out.println("Please enter the real part and imaginary part of the first imaginary number");
int x = input.nextInt();
int y = input.nextInt();
Complex complex1 = new Complex(x, y);
System.out.println("Please enter the real part and imaginary part of the second imaginary number");
x = input.nextInt();
y = input.nextInt();
Complex complex2 = new Complex(x, y);
if (a == 1) {
System.out.println(complex1.ComplexAdd(complex2));
}
if (a == 2) {
System.out.println(complex1.ComplexSub(complex2));
}
if (a == 3) {
System.out.println(complex1.ComplexMulti(complex2));
}
if (a == 4) {
System.out.println(complex1.ComplexDiv(complex2));
}
if (a == 5) {
if (complex1.compareTo(complex2) == 1) {
System.out.println("The real part of the second imaginary number is larger");
} else {
System.out.println("The real part of the first imaginary number is larger");
}
}
if (a == 6) {
if (complex1.carry(complex2) == 1) {
System.out.println("The imaginary part of the second imaginary number is larger");
} else {
System.out.println("The imaginary part of the first imaginary number is larger");
}
}
}
}
}
运行结果截图
(四)远程有理数计算器
package RationalNumberCalculator;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/27
* \* Time: 21:29
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import java.util.StringTokenizer;
public class Fraction {
int fenzi, fenmu;
char ch;
public Fraction(String str) {
StringTokenizer st = new StringTokenizer(str, "/", true);
this.fenzi = Integer.parseInt(st.nextToken());
this.ch = st.nextToken().charAt(0);
this.fenmu = Integer.parseInt(st.nextToken());
}
public Fraction yuefen(int fz, int fm) {
int i;
for (i = 2; i <= fz && i <= fm; i++) {
if (fz % i == 0 && fm % i == 0) {
fz = fz / i;
fm = fm / i;
}
}
Fraction result = new Fraction(fz + "/" + fm);
return result;
}
public Fraction getJia(Fraction x) {
int newFenmu = fenmu * x.fenmu;
int newFenzi = fenzi * x.fenmu + x.fenzi * fenmu;
return yuefen(newFenzi, newFenmu);
}
public Fraction getJian(Fraction x) {
int newFenmu = fenmu * x.fenmu;
int newFenzi = fenzi * x.fenmu - x.fenzi * fenmu;
return yuefen(newFenzi, newFenmu);
}
public Fraction getCheng(Fraction x) {
int newFenmu = fenmu * x.fenmu;
int newFenzi = fenzi * x.fenzi;
return yuefen(newFenzi, newFenmu);
}
public Fraction getChu(Fraction x) {
int newFenmu = fenmu * x.fenzi;
int newFenzi = fenzi * x.fenmu;
return yuefen(newFenzi, newFenmu);
}
@Override
public String toString() {
return fenzi + "/" + fenmu;
}
}
package RationalNumberCalculator;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/27
* \* Time: 21:28
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
/**
* Created by besti on 2019/9/29.
*/
public class Server1923 {
private static Fraction frac2;
private static Fraction frac1;
private static String a,b;
private static char ch;
private static Fraction result = null;
public static void main(String[] args) throws IOException {
//1.建立一个服务器Socket(ServerSocket)绑定指定端口
ServerSocket serverSocket=new ServerSocket(8809);
//2.使用accept()方法阻止等待监听,获得新连接
Socket socket=serverSocket.accept();
//3.获得输入流
InputStream inputStream=socket.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
//获得输出流
OutputStream outputStream=socket.getOutputStream();
PrintWriter printWriter=new PrintWriter(outputStream);
//4.读取用户输入信息
String info=null;
System.out.println("服务器已经建立......");
while(!((info = bufferedReader.readLine()) ==null)){
System.out.println("我是服务器,用户信息为:" + info);
StringTokenizer st = new StringTokenizer(info, " ", false);
a=st.nextToken();
ch=st.nextToken().charAt(0);
b=st.nextToken();
frac1=new Fraction(a);
frac2=new Fraction(b);
switch (ch)
{
case '+':
result=frac1.getJia(frac2);
break;
case '-':
result=frac1.getJian(frac2);
break;
case '*':
result=frac1.getCheng(frac2);
break;
case '/':
result=frac1.getChu(frac2);
break;
default:
break;
}
}
//给客户一个响应
String reply=frac1+String.valueOf(ch)+frac2+"="+result;
printWriter.write(reply);
printWriter.flush();
//5.关闭资源
printWriter.close();
outputStream.close();
bufferedReader.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
package RationalNumberCalculator;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/27
* \* Time: 21:27
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
**/
import java.io.*;
import java.net.Socket;
/**
* Created by besti on 2018/6/9.
*/
public class SocketClient2 {
public static void main(String[] args) throws IOException {
//1.建立客户端Socket连接,指定服务器位置和端口
Socket socket = new Socket("127.0.0.1", 8809);
// Socket socket = new Socket("172.16.43.187",8800);
//2.得到socket读写流
OutputStream outputStream = socket.getOutputStream();
// PrintWriter printWriter = new PrintWriter(outputStream);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
//输入流
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
//3.利用流按照一定的操作,对socket进行读写操作
String info1 = " 1/4 + 1/6";
// String info = new String(info1.getBytes("GBK"),"utf-8");
// printWriter.write(info);
// printWriter.flush();
outputStreamWriter.write(info1);
outputStreamWriter.flush();
socket.shutdownOutput();
//接收服务器的响应
String reply = null;
while (!((reply = bufferedReader.readLine()) == null)) {
System.out.println("接收服务器的信息为:" + reply);
}
//4.关闭资源
bufferedReader.close();
inputStream.close();
outputStreamWriter.close();
//printWriter.close();
outputStream.close();
socket.close();
}
}
运行结果截图
(五)远程复数计算器
服务器端:
package complexRemoteCalculator;
/*
\* Created with IntelliJ IDEA.
\* User: Shape Of My Heart
\* Date: 2020/10/25
\* Time: 16:21
\* Besides,some of the best things in life are total mistakes.
\* Description:
\
import NBE2.Complex;
import RSA.RSAEncrypt;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class calculatorServer {
/*
* java.net.ServerSocket
* 运行在服务端的ServerSocket主要有两个作用
* 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的。
*
* 2:监听该端口,这样一旦一个客户端通过该端口尝试建立连接时,ServerSocket就会自动实例化
* 一个Socket,那么通过这个Socket就可以与客户端对等并进行数据交互了。
*/
private ServerSocket server;
public calculatorServer() {
try {
/*
* 实例化ServerSocket的同时要向系统
* 申请服务端口,客户端就是通过这个端
* 口与服务端建立连接的。
*/
System.out.println("正在启动服务端...");
server = new ServerSocket(8080);
System.out.println("服务端启动完毕!");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
calculatorServer server1 = new calculatorServer();
server1.start();
}
public void start() {
try {
/*
* Socket accept()
* ServerSocket的accept方法是一个阻塞
* 方法,调用后会一直等待,直到一个客户端
* 建立连接为止,此时该方法会返回一个Socket
* 实例,通过这个Socket就可以与刚连接上的
* 客户端进行数据交互了。
* 多次调用accept可以等待不同客户端的连接
*/
RSAEncrypt.genKeyPair();
while (true) {
System.out.println("等待客户端连接...");
Socket socket = server.accept();
System.out.println("一个客户端连接了!");
/*
* 通过Socket获取输入流,可以读取到远端
* 计算机发送过来的字节。
*/
InputStream in = socket.getInputStream();
InputStreamReader isr
= new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader br
= new BufferedReader(isr);
Scanner scanner = new Scanner(System.in);
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw, true);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("客户端问:" + line);
String[] strs = line.split(" ");
int a = Integer.parseInt(strs[0]);
double X1 = Double.parseDouble(strs[1]);
double X2 = Double.parseDouble(strs[2]);
double X3 = Double.parseDouble(strs[3]);
double X4 = Double.parseDouble(strs[4]);
Complex complex1 = new Complex(X1, X2);
Complex complex2 = new Complex(X3, X4);
if (a == 1) {
String line1 = String.valueOf(complex1.ComplexAdd(complex2));
pw.println(line1);
}
if (a == 2) {
String line1 = String.valueOf(complex1.ComplexSub(complex2));
pw.println(line1);
}
if (a == 3) {
String line1 = String.valueOf(complex1.ComplexMulti(complex2));
pw.println(line1);
}
if (a == 4) {
String line1 = String.valueOf(complex1.ComplexDiv(complex2));
pw.println(line1);
}
if (a == 5) {
if (complex1.compareTo(complex2) == 1) {
System.out.println("The real part of the second imaginary number is larger");
String line1 = "The real part of the second imaginary number is larger";
pw.println(line1);
} else {
System.out.println("The real part of the first imaginary number is larger");
String line1 = "The real part of the first imaginary number is larger";
pw.println(line1);
}
}
if (a == 6) {
if (complex1.carry(complex2) == 1) {
System.out.println("The imaginary part of the second imaginary number is larger");
String line1 = "The imaginary part of the second imaginary number is larger";
pw.println(line1);
} else {
System.out.println("The imaginary part of the first imaginary number is larger");
String line1 = "The imaginary part of the first imaginary number is larger";
pw.println(line1);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
客户端:
package complexRemoteCalculator;
/**
* \* Created with IntelliJ IDEA.
* \* User: Shape Of My Heart
* \* Date: 2020/10/25
* \* Time: 16:20
* \* Besides,some of the best things in life are total mistakes.
* \* Description:
* \
*
* @author Shape Of My Heart
*/
import NBE2.Complex;
import RSA.RSAEncrypt;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
public class calculatorClient {
/*
* java.net.Socket 套接字
* 封装了TCP协议的通讯细节,使得我们可以通过它
* 来与远端计算机建立TCP连接,并利用两个流的读写
* 完成数据交互。
*/
private Socket socket;
/**
* 构造方法,用来初始化客户端
*/
public calculatorClient() {
try {
/*
* Socket实例化是需要传入两个参数
* 参数1:服务端IP地址
* 参数2:服务端程序申请的端口
* 我们通过IP可以找到网络上的服务端计算机
* 通过端口可以连接到服务端计算机上运行的
* 服务端应用程序了。
* 注意:
* 实例化Socket的过程就是连接的过程,若
* 服务端没有响应这里会抛出异常。
*/
System.out.println("正在连接服务端...");
socket = new Socket("127.0.0.1", 8080);
System.out.println("与服务端成功建立连接!");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
calculatorClient client1 = new calculatorClient();
client1.start();
}
/**
* 客户端开始工作的方法
*/
public void start() {
try {
Scanner scanner = new Scanner(System.in);
/*
* Socket提供的方法:
* OutputStream getOutputStream()
* 该方法获取的输出流是一个字节输出流
* 通过这个流写出的字节会通过网络发送
* 到远端计算机上(对于客户端这边而言,
* 远端计算机指的就是服务端了。)
*/
InputStream in = null;
try {
in = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
InputStreamReader isr = null;
isr = new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw, true);
RSAEncrypt.genKeyPair();
String line2 = null;
while (true) {
System.out.println(" Welcome!This is a complex remote calculator.\n");
System.out.println("What kind of operations do you want?");
System.out.println("1.Addition");
System.out.println("2.Subtraction");
System.out.println("3.Multiplication");
System.out.println("4.Division");
System.out.println("5.Compare the size of the real part");
System.out.println("6.Compare the size of imaginary part");
System.out.println("7.Quit");
Scanner input = new Scanner(System.in);
int a = input.nextInt();
if (a < 1 || a > 7) {
System.out.println("error!please choose again");
}
System.out.println("Please enter the real part and imaginary part of the first imaginary number");
int x = input.nextInt();
int y = input.nextInt();
Complex complex1 = new Complex(x, y);
System.out.println("Please enter the real part and imaginary part of the second imaginary number");
x = input.nextInt();
y = input.nextInt();
Complex complex2 = new Complex(x, y);
String m1 = String.valueOf(complex1.getRealPart());
String m2 = String.valueOf(complex1.getImagePart());
String n1 = String.valueOf(complex2.getRealPart());
String n2 = String.valueOf(complex2.getImagePart());
String line = a + " " + m1 + " " + m2 + " " + n1 + " " + n2;
pw.println(line);
try {
if (!((line2 = br.readLine()) != null)) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("服务端计算结果为:" + line2);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果截图
三、实验过程中遇到的问题和解决过程
- 问题1:当主机为客户端时无法连接到对方IP地址
- 问题1解决方案:关闭WINDOWS防火墙
四、心得体会
- 在这次实验过程中,我遇到了许多问题,其中既有知识上的漏洞,也有不细心导致的马虎,这一切都补充,完善,丰富,扩展了我的计算机知识体系。在不断修复问题的过程中,我使用了很多方式去查询资料,例如:《数据结构与面向对象程序设计》,博客园平台,CSDN平台,码云平台,知乎app,等。在Socket套接字的使用中,我还进一步熟悉了Intellij IDEA这个平台的使用与运行方式,提高了自己自主学习的能力,为我接下来学习数据结构以及JAVA语言程序设计打下了坚实的基础,并在不断探索的过程中逐步提升了自己。