diff --git a/Core/Crypto.java b/Core/Crypto.java
index 88c2f6c..9d48f66 100644
--- a/Core/Crypto.java
+++ b/Core/Crypto.java
@@ -5,6 +5,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * 加解密类
+ */
public class Crypto {
private String filePath; // 文件路径
private int depth = 5; // 加密深度(指对每个字节进行多少次操作)
@@ -12,16 +15,22 @@ public class Crypto {
private String encryptedSuffix; // 加上crypt后的后缀名
private String sourceSuffix; // 原始后缀名
private boolean isEncrypt = true; // 当前要进行的是什么操作,true为加密,false为解密
-
// 用于进度显示
private double fileLength; // 文件总字节数
private double currentProgress; // 当前已处理的字节数
+
+ public double getFileLength() {
+ return fileLength;
+ }
+ public double getCurrentProgress() {
+ return currentProgress;
+ }
+
/**
* 导入参数:filePath:String
*
导入后立刻进行处理
* 1、文件是否存在
* 2、提取后缀名
- *
* @param _filePath 需要加解密的文件路径
*/
private void filePath(String _filePath) {
@@ -72,26 +81,30 @@ public float ReturnProgress() {
return (float) (currentProgress / fileLength);
}
+
+
/**
* Crypto类主要函数,传入参数并开始加解密操作
- *
* @param _filePath 文件路径
* @param keyStr 作为密钥的字符串
+ * @throws Exception 可能有Null,FileNotFound
*/
public void Crypt(String _filePath, String keyStr) throws Exception{
- // 录入参数
+ // 录入参数并进行相关处理
filePath(_filePath);
key(keyStr);
//
File sourceFile = new File(filePath);
+ if(!sourceFile.exists())
+ throw new NullPointerException();
File outputFile = null;
- // 确认输出文件的文件名
+ // 确认输出文件的后缀名
if (isEncrypt) {
outputFile = new File(filePath.replace(sourceSuffix, "crypt" + sourceSuffix));
} else {
outputFile = new File(filePath.replace(encryptedSuffix, sourceSuffix));
}
- //
+ // 创建各种流
InputStream in = null;
OutputStream out = null;
if (!outputFile.exists())
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
index f3e3c21..f98b469 100644
--- a/META-INF/MANIFEST.MF
+++ b/META-INF/MANIFEST.MF
@@ -1,3 +1,3 @@
Manifest-Version: 1.0
-Main-Class: UI.Main
+Main-Class: UI.MainUI
diff --git a/UI/AboutWindow.java b/UI/AboutWindow.java
new file mode 100644
index 0000000..af6b419
--- /dev/null
+++ b/UI/AboutWindow.java
@@ -0,0 +1,59 @@
+package UI;
+
+import javax.swing.*;
+import java.awt.*;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+public class AboutWindow extends JFrame{
+ AboutWindow(){
+ Font font = new Font("Microsoft YaHei", Font.PLAIN, 12);
+ // 读取About.txt内的说明信息
+ String strAbout = "";
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("Resource/About.txt"), StandardCharsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ String tmp = "";
+ while ((tmp = reader.readLine()) != null) {
+ sb.append(tmp + "\n");
+ }
+ strAbout = sb.toString();
+ reader.close();
+ } catch (FileNotFoundException ex) {
+ ex.printStackTrace();
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
+ }
+ // 创建窗口
+ setTitle("关于");
+ JPanel panel = new JPanel(new BorderLayout());
+ JTextPane text = new JTextPane();
+ JScrollPane scrollPane = new JScrollPane(text);
+ panel.add(scrollPane, BorderLayout.CENTER);
+ text.setBackground(new Color(70, 70, 70));
+ text.setForeground(new Color(139, 150, 158));
+ text.setFont(font);
+ text.setEditable(false);
+ // 逐字输出关于信息
+ String finalStrAbout = strAbout;
+ new Thread(() -> {
+ for (int i = 0; i < finalStrAbout.length(); i++) {
+ try {
+ Thread.sleep(100);
+ text.setText(text.getText() + finalStrAbout.charAt(i));
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }).start();
+
+ setContentPane(panel);
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+ setBounds(100, 100, 420, 500);
+ setVisible(true);
+ }
+
+}
diff --git a/UI/FX.java b/UI/FX.java
new file mode 100644
index 0000000..4392b6d
--- /dev/null
+++ b/UI/FX.java
@@ -0,0 +1,309 @@
+package UI;
+
+import Core.Crypto;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Random;
+
+/**
+ * 动画效果窗口
+ */
+public class FX extends JFrame {
+ private JPanel mainPanel, minorPanel; // 主Panel 和 副Panel
+ private JLabel lblStatus; // 表示状态的Label
+ private JTextField[][] textNodes; // 每个格子都是一个TextField,这是个TextFiled数组
+ private Crypto crypto; // 存放Crypto的实例
+ private int timeRatio = 50; // 决定动画持续时间的系数,50约为12s
+
+ // 预先定义防止反复创建变量,优化性能
+ private Color colorRed = new Color(150,32,32); // 红色
+ private int redWaveRange = 80; // 红色颜色波动范围
+ private Color colorGreen = new Color(54, 150, 48); // 绿色
+ private int greenWaveRange = 80; // 绿色颜色波动范围
+
+ /**
+ * FX的主函数,仅供单独打开动画调试用
+ * @param args 命令行参数
+ */
+ public static void main(String[] args){
+ // 若需仅打开动画,便启动这个主函数,并设置上面的timeRatio以控制持续时间
+ new FX(null);
+ }
+
+ /**
+ * 从时间秒数到timeRatio系数的转换函数
+ * 利用函数拟合器获得,基本为线性,相关度0.99996
+ * @param secs 秒数
+ * @return 返回timeRatio系数
+ */
+ private int secsToRatio(float secs){
+ if(secs<5)
+ return 1;
+
+ double A,B,C,D,X=secs;
+ A = 1.01563088882032E+15;
+ B = -1.00541928494497;
+ C = 176451864312395d;
+ D = -20.3014929981133;
+ return (int)((A-D)/(1+Math.pow(X/C,B))+D);
+ }
+
+ /**
+ * 构造函数
+ * 导入Crypto实例后 判断是否为单独运行动画
+ * 不是:运行{@link FX#SpeedTest()}函数 ({@link FX#SpeedTest()}之后会自动调用下面两个函数)
+ * 是:跳过{@link FX#SpeedTest()}函数,直接运行{@link FX#Initialize()}函数和{@link FX#Start()}函数
+ * @param _crypto 即将运行的{@link Core.Crypto}实例
+ */
+ FX(Crypto _crypto) {
+ crypto = _crypto;
+ if(crypto==null){
+ Initialize();
+ Start();
+ }
+ else if(crypto.getFileLength()<10000) {
+ timeRatio = 1;
+ Initialize();
+ Start();
+ }
+ else{
+ SpeedTest();
+ }
+
+ }
+
+ /**
+ * 初始化界面元素
+ */
+ private void Initialize() {
+ // 基本布局:JFrame(mainPanel:Border(North->minorPanel:Grid(textField[15][8])))
+ mainPanel = new JPanel(new BorderLayout());
+ mainPanel.setBackground(new Color(36, 36, 36));
+ minorPanel = new JPanel(new GridLayout(15, 8,1,1));
+ minorPanel.setBackground(new Color(36, 36, 36));
+ lblStatus = new JLabel("File Encrypting...");
+ lblStatus.setForeground(new Color(139, 150, 158));
+ mainPanel.add(lblStatus, BorderLayout.NORTH);
+ mainPanel.add(minorPanel, BorderLayout.CENTER);
+ // 初始化textNodes数组
+ textNodes = new JTextField[15][8];
+ Font font = new Font("微软雅黑",Font.BOLD,12);
+ Color colorRed = new Color(150,32,32);
+ Color colorBg = new Color(180,180,180);
+ TextBorderUtlis border = new TextBorderUtlis(new Color(36, 36, 36), 0, false);
+ // 设置每一个格子
+ for (int row = 0; row < 15; row++) {
+ for (int col = 0; col < 8; col++) {
+ JTextField textField = textNodes[row][col];
+ textNodes[row][col] = new JTextField("255", 3);
+ textNodes[row][col].setForeground(colorBg);
+ textNodes[row][col].setBackground(colorRed);
+ textNodes[row][col].setHorizontalAlignment(JTextField.CENTER);
+ textNodes[row][col].setBorder(border);
+ textNodes[row][col].setVisible(false);
+ textNodes[row][col].setEditable(false);
+ textNodes[row][col].setFont(font);
+ minorPanel.add(textNodes[row][col]);
+ }
+ }
+ setContentPane(mainPanel);
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+ setVisible(true);
+ setBounds(50,50,300,300);
+ }
+
+ /**
+ * 测试当前系统加解密速度,以确定动画持续市时长
+ */
+ private void SpeedTest() {
+ // 新的线程,用于测速:用时1s
+ new Thread(() -> {
+ long start, end;
+ float cryStart, cryEnd, speed = 0;
+ for (int i = 0; i < 10; i++) {
+ start = System.currentTimeMillis();
+ cryStart = (int) crypto.getCurrentProgress();
+ // 等待
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ //
+ end = System.currentTimeMillis();
+ cryEnd = (int) crypto.getCurrentProgress();
+ speed += (int) ((cryEnd - cryStart) / (end - start));
+ }
+ // 测试完后调用
+ SpeedTestComplete((int) speed / 10);
+ }).start();
+ }
+
+ /**
+ * 测速完成后调用的函数
+ * 在此处计算动画持续时间
+ * 以及调用{@link FX#Initialize()}和{@link FX#Start()}
+ * @param speed 前面测速所得的速度,单位bytes/ms
+ */
+ private void SpeedTestComplete(int speed) {
+ System.out.println(speed);
+ int secs = (int) (crypto.getFileLength()/(speed*1000));
+ System.out.printf("需要%d秒\n",secs);
+ timeRatio=secsToRatio(secs);
+ Initialize();
+ Start();
+ }
+
+ /**
+ * 开始动画
+ */
+ private void Start() {
+ // counts二维数组用于给每一个格子确定变化次数
+ int counts[][] = new int[15][8];
+ Random rd = new Random();
+ // 填充数据以控制时间
+ for (int row = 0; row < 15; row++) {
+ for (int col = 0; col < 8; col++) {
+ counts[row][col] = rd.nextInt(timeRatio) + 4;// 加4防止动画过短造成视觉效果不佳
+ }
+ }
+ // 开始时格子逐渐显现的过程(逐个设置可见;颜色亮度波动)
+ // 遍历每一个格子并对齐调用nodeActionStart()使颜色变亮一会
+ new Thread(() -> {
+ for (int row = 0; row < 15; row++) {
+ for (int col = 0; col < 8; col++) {
+ try {
+ Thread.sleep(5);
+ nodeActionStart(textNodes[row][col]);
+ textNodes[row][col].setVisible(true);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }).start();
+ // 格子数字变换的效果
+ // 遍历每一个格子,每遍历一次就将其剩余变换次数减1,并随机变换数字或不变
+ new Thread(() -> {
+ while (true) {
+ boolean isComplete = true;
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ for (int row = 0; row < 15; row++) {
+ for (int col = 0; col < 8; col++) {
+ if (counts[row][col] > 0) { // 还未完成
+ // 随机变或不变
+ if(rd.nextInt(2)>0)
+ textNodes[row][col].setText((rd.nextInt(254) + 1) + "");
+ counts[row][col]--;
+ isComplete = false;
+ } else if (counts[row][col] == 0) { // 已完成
+ // 完成的格子就变成绿色,字改为0,然后调用nodeActionComplete()使颜色变亮一会
+ counts[row][col]--;
+ textNodes[row][col].setText("0");
+ textNodes[row][col].setBackground(colorGreen);
+ nodeActionComplete(textNodes[row][col]);
+ }
+ }
+ }
+ // 如果有任意一个格子还没完成就不会执行
+ if (isComplete) {
+ // 全部完成时,遍历每一个格子并调用nodeActionComplete()使颜色变亮一会
+ new Thread(() -> {
+ for (int row = 0; row < 15; row++) {
+ for (int col = 0; col < 8; col++) {
+ try {
+ Thread.sleep(5);
+ nodeActionComplete(textNodes[row][col]);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ // 等待1s后调用frameActionShrink()关闭动画
+ new Thread(()->{
+ try {
+ Thread.sleep(1000);
+ frameActionShrink();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }).start();
+ }).start();
+ lblStatus.setText("File Encrypted");
+ break;
+ }
+ }
+ }).start();
+ }
+
+ /**
+ * 格子开始时的动作 (红色:亮度上升再回落)
+ * @param text TextFiled格子实例
+ */
+ private void nodeActionStart(JTextField text) {
+ new Thread(() -> {
+ for (int i = 0; i < 80; i += 8) {
+ try {
+ Thread.sleep(20);
+ text.setBackground(new Color(150 + i, 32, 32));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ for (int i = 0; i < 80; i += 8) {
+ try {
+ Thread.sleep(20);
+ text.setBackground(new Color(230 - i, 32, 32));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+ /**
+ * 格子完成时的动作 (绿色:亮度上升再回落)
+ * @param text TextFiled格子实例
+ */
+ private void nodeActionComplete(JTextField text) {
+ new Thread(() -> {
+ for (int i = 0; i < 80; i += 8) {
+ try {
+ Thread.sleep(20);
+ text.setBackground(new Color(54, 150 + i, 48));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ for (int i = 0; i < 80; i += 8) {
+ try {
+ Thread.sleep(20);
+ text.setBackground(new Color(54, 230 - i, 48));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+ /**
+ * 动画完成时的动作 (窗口向上收缩并最后关闭)
+ */
+ private void frameActionShrink(){
+ new Thread(() -> {
+ for (int i = 0; i < getHeight(); i ++) {
+ try {
+ Thread.sleep(10);
+ setSize(getWidth(),getHeight()-(int)Math.sqrt(i));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ dispose();
+ }).start();
+ }
+
+}
diff --git a/UI/Main.java b/UI/Main.java
deleted file mode 100644
index 989d99d..0000000
--- a/UI/Main.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package UI;
-
-import UI.MainUI;
-
-import java.io.IOException;
-
-public class Main {
- public static void main(String args[]){
- MainUI ui = new MainUI();
- }
-
-}
diff --git a/UI/MainUI.form b/UI/MainUI.form
index ea9503d..7875f22 100644
--- a/UI/MainUI.form
+++ b/UI/MainUI.form
@@ -17,6 +17,7 @@
+
diff --git a/UI/MainUI.java b/UI/MainUI.java
index ac8c343..8459009 100644
--- a/UI/MainUI.java
+++ b/UI/MainUI.java
@@ -14,8 +14,7 @@
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Path;
+import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.*;
@@ -30,14 +29,16 @@ public class MainUI extends JFrame {
private JTextField textKey; // 密钥文本框
private JProgressBar progressBar; // 进度条
- private final Crypto crypto = new Crypto(); // Crypto类的唯一实例
+ private Crypto crypto = new Crypto(); // Crypto类的唯一实例
+
+ public static void main(String[] args) {
+ new MainUI();
+ }
/**
- * MainUI构造函数,目前主要负责事件添加和设置一些初始值
+ * 用于分散构造函数:给窗口添加菜单栏(包含一个关于按钮)
*/
- public MainUI() {
- // Swing GUI编辑器生成代码
- $$$setupUI$$$();
+ private void addAboutMenu() {
// 添加一个顶部菜单栏
Font font = new Font("Microsoft YaHei", Font.PLAIN, 12);
Color fontColor = new Color(139, 150, 158);
@@ -63,50 +64,34 @@ public MainUI() {
menuBar.setBackground(backColor);
menuBar.setBorder(border);
setJMenuBar(menuBar);
- // 设置菜单栏各事件
+ // 设置菜单栏”关于“事件
menuItemAbout.addActionListener(e -> {
- // 读取About.txt内的说明信息
- String strAbout = "";
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("Resource/About.txt")));
- StringBuilder sb = new StringBuilder();
- String tmp = "";
- while ((tmp = reader.readLine()) != null) {
- sb.append(tmp + "\n");
- }
- strAbout = sb.toString();
- reader.close();
- } catch (FileNotFoundException ex) {
- ex.printStackTrace();
- } catch (IOException ioException) {
- ioException.printStackTrace();
- }
- // 创建窗口
- JFrame frame = new JFrame("关于");
- JPanel panel = new JPanel(new BorderLayout());
- JTextPane text = new JTextPane();
- JScrollPane scrollPane = new JScrollPane(text);
- panel.add(scrollPane, BorderLayout.CENTER);
- text.setBackground(new Color(70, 70, 70));
- text.setForeground(new Color(139, 150, 158));
- text.setFont(font);
- text.setEditable(false);
- String finalStrAbout = strAbout;
- new Thread(() -> {
- for (int i = 0; i < finalStrAbout.length(); i++) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException ex) {
- ex.printStackTrace();
- }
- text.setText(text.getText() + finalStrAbout.charAt(i));
- }
- }).start();
-
- frame.setContentPane(panel);
- frame.setBounds(100, 100, 420, 500);
- frame.setVisible(true);
+ new AboutWindow();
});
+ }
+
+ /**
+ * 用于分散构造函数:设置组件边框
+ */
+ private void setBorder() {
+ LineBorder border2 = new TextBorderUtlis(new Color(70, 70, 70), 2, false);
+ textFilePath.setBorder(border2);
+ textKey.setBorder(border2);
+ btnGenerateRandomKey.setBorder(border2);
+ progressBar.setBorder(border2);
+ btnEncryptDecrypt.setBorder(new TextBorderUtlis(new Color(70, 70, 70), 5, false));
+ }
+
+ /**
+ * MainUI构造函数,目前主要负责事件添加和设置一些初始值
+ */
+ public MainUI() {
+ // Swing GUI编辑器生成代码
+ $$$setupUI$$$();
+ // 添加菜单栏
+ addAboutMenu();
+ // 设置进度条最大值
+ progressBar.setMaximum(100);
// 拖入文件的事件
textFilePath.setTransferHandler(new TransferHandler() {
@Override
@@ -142,8 +127,6 @@ public boolean canImport(JComponent comp, DataFlavor[] flavors) {
return false;
}
});
- // 设置进度条最大值
- progressBar.setMaximum(100);
// 按钮“加密 / 解密”的点击事件
btnEncryptDecrypt.addActionListener(e -> {
btnEncryptDecrypt.setEnabled(false);
@@ -153,8 +136,7 @@ public boolean canImport(JComponent comp, DataFlavor[] flavors) {
// 没写就提示
if (lblStatus.getText().length() == 20) {
btnEncryptDecrypt.setEnabled(true);
- }
- else if (lblStatus.getText().startsWith("请先输入文件路径和密钥")) {
+ } else if (lblStatus.getText().startsWith("请先输入文件路径和密钥")) {
btnEncryptDecrypt.setEnabled(true);
lblStatus.setText(lblStatus.getText().replace("。", "") + "!");
} else {
@@ -163,7 +145,8 @@ else if (lblStatus.getText().startsWith("请先输入文件路径和密钥")) {
}
} else {
// 写了就开始运行加解密
- new BackRunnerCrypt().start();
+ new FX(crypto);
+ new BW_Crypt().start();
}
lblStatus.requestFocus();
});
@@ -198,18 +181,13 @@ public void focusLost(FocusEvent e) {
SecureRandom rd = new SecureRandom();
String myAscii = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
StringBuilder keyStr = new StringBuilder();
- for (int i = 0; i < 16; i++) {
+ for (int i = 0; i < 32; i++) {
keyStr.append(myAscii.charAt(rd.nextInt(62)));
}
textKey.setText(keyStr.toString());
});
// 边框设置
- LineBorder border2 = new TextBorderUtlis(new Color(70, 70, 70), 2, false);
- textFilePath.setBorder(border2);
- textKey.setBorder(border2);
- btnGenerateRandomKey.setBorder(border2);
- progressBar.setBorder(border2);
- btnEncryptDecrypt.setBorder(new TextBorderUtlis(new Color(70, 70, 70), 5, false));
+ setBorder();
// 修改窗口风格为当前系统对应的风格
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
@@ -220,8 +198,9 @@ public void focusLost(FocusEvent e) {
setContentPane(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
- setTitle("Crypto v0.1.3 by LZHJK");
+ setTitle("Crypto");
setVisible(true);
+ setLocation(300, 100);
pack();
// 设置焦点位置
textKey.requestFocus();
@@ -230,7 +209,7 @@ public void focusLost(FocusEvent e) {
/**
* 用于后台运行加解密
*/
- class BackRunnerCrypt implements Runnable {
+ class BW_Crypt implements Runnable {
public void start() {
Thread t = new Thread(this);
t.start();
@@ -240,7 +219,7 @@ public void run() {
boolean isError = false;
lblStatus.setText("运行中...");
// 再运行一个进程控制进度条
- new BackRunnerShowProgress().start();
+ new BW_ShowProgress().start();
try {
crypto.Crypt(textFilePath.getText(), textKey.getText());
} catch (NullPointerException e) {
@@ -254,6 +233,7 @@ public void run() {
if (!isError)
lblStatus.setText("成功。");
btnEncryptDecrypt.setEnabled(true);
+ crypto = new Crypto();
}
}
@@ -261,7 +241,7 @@ public void run() {
/**
* 控制进度条的显示
*/
- class BackRunnerShowProgress implements Runnable {
+ class BW_ShowProgress implements Runnable {
public void start() {
Thread t = new Thread(this);
t.start();
@@ -306,6 +286,7 @@ public void run() {
textFilePath = new JTextField();
textFilePath.setBackground(new Color(-13487566));
textFilePath.setForeground(new Color(-7629154));
+ textFilePath.setHorizontalAlignment(10);
textFilePath.setText("支持拖拽文件至此");
mainPanel.add(textFilePath, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(300, 30), null, 0, false));
final JLabel label1 = new JLabel();
diff --git a/UI/Resource/About.txt b/UI/Resource/About.txt
index ed5bc14..cff3a24 100644
--- a/UI/Resource/About.txt
+++ b/UI/Resource/About.txt
@@ -1,16 +1,21 @@
Crypto
-Version 0.1.2
+Version 0.2.0
-Powered by Java / Intellj IDEA
+Powered by Java / IntelliJ IDEA
Lzhjk Presents
+v0.2.0 新添加动画效果
加密算法:
密钥字符串的hashCode作为Random类的种子
对文件的每一个字节,取五次随机值对其进行异或运算
利用Random的伪随机数特性和异或运算的可逆性
- 缺陷很明显
+ 缺陷是
简单的异或运算以及字符串生成哈希值可能的重复问题
+
+
+Any questions?
+ Please mail to xxlzhjkxx@gmail.com
\ No newline at end of file