();
78 |
79 | static {
80 | for (ResultCodeEnum type : ResultCodeEnum.values()) {
81 | interToEnum.put(type.getCode(), type);
82 | }
83 | }
84 |
85 | public String getCode() {
86 | return code;
87 | }
88 |
89 | public void setCode(String code) {
90 | this.code = code;
91 | }
92 |
93 | public String getMessage() {
94 | return message;
95 | }
96 |
97 | public void setMessage(String message) {
98 | this.message = message;
99 | }
100 |
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/src/main/java/com/yyan/utils/ServiceException.java:
--------------------------------------------------------------------------------
1 | package com.yyan.utils;//package com.yyan.utils;
2 | //
3 | //public class ServiceException extends RuntimeException {
4 | //
5 | // private Integer code;
6 | // private String desc;
7 | //
8 | // public ServiceException(Integer code, String desc) {
9 | // super(desc);
10 | // this.code = code;
11 | // this.desc = desc;
12 | // }
13 | //
14 | // public Integer getCode() {
15 | // return code;
16 | // }
17 | //
18 | // public void setCode(Integer code) {
19 | // this.code = code;
20 | // }
21 | //
22 | // public String getDesc() {
23 | // return desc;
24 | // }
25 | //
26 | // public void setDesc(String desc) {
27 | // this.desc = desc;
28 | // }
29 | //}
--------------------------------------------------------------------------------
/src/main/java/com/yyan/utils/SessionUtil.java:
--------------------------------------------------------------------------------
1 | //package com.yyan.utils;
2 | //
3 | //import org.springframework.beans.factory.annotation.Autowired;
4 | //
5 | //import javax.servlet.http.HttpSession;
6 | //
7 | //public class SessionUtil {
8 | // @Autowired
9 | // private HttpSession session;
10 | //
11 | // /**
12 | // * 获取用户 id
13 | // *
14 | // * @return
15 | // */
16 | // public String getUserIdSession() {
17 | // return (String) session.getAttribute("userId");
18 | // }
19 | //
20 | //
21 | //}
22 |
--------------------------------------------------------------------------------
/src/main/java/com/yyan/utils/StringUtil.java:
--------------------------------------------------------------------------------
1 | package com.yyan.utils;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileNotFoundException;
5 | import java.math.BigInteger;
6 | import java.security.MessageDigest;
7 |
8 | public class StringUtil {
9 |
10 | /**
11 | * 创建数字签名
12 | *
13 | * Java方式可以实现的加密方式有很多,例如BASE、MD、RSA、SHA等等,
14 | * 我在这里选用了SHA256这种加密方式,SHA(Secure Hash Algorithm)
15 | * 安全散列算法,这种算法的特点是数据的少量更改会在Hash值中产生不可预知的大量更改,
16 | * hash值用作表示大量数据的固定大小的唯一值,而SHA256算法的hash值大小为256位。
17 | * 之所以选用SHA256是因为它的大小正合适,一方面产生重复hash值的可能性很小,
18 | * 另一方面在区块链实际应用过程中,有可能会产生大量的区块,而使得信息量很大
19 | * ,那么256位的大小就比较恰当了
20 | *
21 | * @param input
22 | * @return
23 | */
24 |
25 | public static String applySha256(String input) {
26 | try {
27 | MessageDigest digest = MessageDigest.getInstance("SHA-256");
28 | //将sha256应用于我们的输入
29 | byte[] hash = digest.digest(input.getBytes("UTF-8"));
30 | StringBuffer hexString = new StringBuffer(); // 它将包含hash作为hexidecima
31 |
32 | for (int i = 0; i < hash.length; i++) {
33 | String hex = Integer.toHexString(0xff & hash[i]);
34 | if (hex.length() == 1) hexString.append('0');
35 | hexString.append(hex);
36 | }
37 | return hexString.toString();
38 | } catch (Exception e) {
39 | throw new RuntimeException(e);
40 | }
41 | }
42 |
43 |
44 | /**
45 | * 对字符串进行md5
46 | * @param input
47 | * @return
48 | */
49 | public static String md5Code(String input) {
50 | try {
51 | MessageDigest digest = MessageDigest.getInstance("MD5");
52 | //将sha256应用于我们的输入
53 | byte[] hash = digest.digest(input.getBytes("UTF-8"));
54 | StringBuffer hexString = new StringBuffer(); // 它将包含hash作为hexidecima
55 |
56 | for (int i = 0; i < hash.length; i++) {
57 | String hex = Integer.toHexString(0xff & hash[i]);
58 | if (hex.length() == 1) hexString.append('0');
59 | hexString.append(hex);
60 | }
61 | return hexString.toString();
62 | } catch (Exception e) {
63 | throw new RuntimeException(e);
64 | }
65 | }
66 |
67 |
68 |
69 |
70 | // public static void main(String[] args) {
71 | // try {
72 | // //此处我测试的是我本机jdk源码文件的MD5值
73 | // String filePath = "C:\\Program Files\\Java\\jdk1.7.0_45\\src.zip";
74 | // FileInputStream fis = new FileInputStream(filePath);
75 | // String md5Hashcode = fileHashCode(fis);
76 | //
77 | // System.out.println(md5Hashcode + ":文件的md5值");
78 | //
79 | // //System.out.println(-100 & 0xff);
80 | // } catch (FileNotFoundException e) {
81 | // e.printStackTrace();
82 | // }
83 | // }
84 | //
85 |
86 |
87 |
88 |
89 | /**
90 | * java获取文件的SHA-256值
91 | *
92 | * @param fis 输入流
93 | * @return
94 | */
95 |
96 | public static String fileHashCode(FileInputStream fis) {
97 | try {
98 | //SHA-256,如果想使用SHA-1或MD5,则传入SHA-1,MD5
99 | MessageDigest md = MessageDigest.getInstance("SHA-256");
100 |
101 | //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。
102 | byte[] buffer = new byte[1024];
103 | int length = -1;
104 | while ((length = fis.read(buffer, 0, 1024)) != -1) {
105 | md.update(buffer, 0, length);
106 | }
107 | fis.close();
108 | //转换并返回包含16个元素字节数组,返回数值范围为-128到127
109 | byte[] bytes = md.digest();
110 | BigInteger bigInt = new BigInteger(1, bytes);//1代表绝对值
111 | return bigInt.toString(16);//转换为16进制
112 | } catch (Exception e) {
113 | e.printStackTrace();
114 | return "";
115 | }
116 | }
117 |
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | # 单个文件大小
2 | spring.servlet.multipart.max-file-size=10MB
3 | # 总文件大小
4 | spring.servlet.multipart.max-request-size=50MB
5 |
6 | # 数据库相关
7 | #数据库驱动
8 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
9 | spring.datasource.url=jdbc:mysql://localhost:3306/des?allowMultiQueries=true
10 | #账号
11 | spring.datasource.username=root
12 | #密码
13 | spring.datasource.password=ld20110702
14 | # 数据库连接池
15 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
16 |
17 | # mybatis 配置
18 | # 扫描路径
19 | mybatis.mapper-locations=classpath:mapper/*.xml
20 | # 打印 mybatis 执行的 SQL 语句
21 | mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
22 | # 包别名
23 | mybatis.type-aliases-package=com.yyan.pojo
24 |
25 | # JPA 相关
26 | # 第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构
27 | spring.jpa.hibernate.ddl-auto=update
28 | # 控制台输出 sql 语句
29 | spring.jpa.show-sql=true
30 |
31 | spring.mvc.async.request-timeout=2000s
32 |
33 | spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
34 | spring.jackson.time-zone=GMT+8
35 |
36 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/block.xml:
--------------------------------------------------------------------------------
1 |
insert into block(
id, userId,preHash,fileUrl,timeStamp,category,nonce,hash,height,createTime,updateTime
) values
(uuid(), #{userId},#{preHash},#{fileUrl},#{timeStamp},#{category},#{nonce},#{hash},#{height}, now(), now())
and userId= #{userId}
and id=#{id}
and category=#{category}
and hash=#{hash}
--------------------------------------------------------------------------------
/src/main/resources/mapper/user.xml:
--------------------------------------------------------------------------------
1 |
insert into user(id, phone,password,email,name,createTime,updateTime) values
(uuid(), #{phone},#{password},#{email},#{name}, now(), now())
update user
email=#{email},
password=#{password},
updateTime=now()
where 1=1 and id = #{id}
--------------------------------------------------------------------------------
/src/main/resources/static/images/18.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/18.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/22.jpg
--------------------------------------------------------------------------------
/src/main/resources/static/images/41a3146d-60de-4e22-8f28-fdd0282aa57f.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/41a3146d-60de-4e22-8f28-fdd0282aa57f.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/76d3b075-f4ca-410c-92ce-67a60bb989c2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/76d3b075-f4ca-410c-92ce-67a60bb989c2.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/79fe5b58-17ed-4c4c-9b25-aef306494227.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/79fe5b58-17ed-4c4c-9b25-aef306494227.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/a75b330d-aa49-4ed6-9c64-d9e8b9dddb6a.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/a75b330d-aa49-4ed6-9c64-d9e8b9dddb6a.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/c5d95b51-9004-469e-9181-1fb8e54684cc.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/c5d95b51-9004-469e-9181-1fb8e54684cc.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/cdc6d6e7-065f-40be-a39f-105ed7585ce3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/cdc6d6e7-065f-40be-a39f-105ed7585ce3.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/d68dc7ea-6576-48f8-b504-c60af8085ae2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/d68dc7ea-6576-48f8-b504-c60af8085ae2.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/images/f43a8555-7a92-479c-92b1-f7cd90072677.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/images/f43a8555-7a92-479c-92b1-f7cd90072677.jpeg
--------------------------------------------------------------------------------
/src/main/resources/static/uploadFile/2020/04/12/963eaad5-4cf7-45fe-a12d-11124af2fac2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ranyanchuan/des-be/673317cab41826ea4abc51045f746459ea0883c8/src/main/resources/static/uploadFile/2020/04/12/963eaad5-4cf7-45fe-a12d-11124af2fac2.jpeg
--------------------------------------------------------------------------------
/src/test/java/TestBlock.java:
--------------------------------------------------------------------------------
1 | //import com.alibaba.fastjson.JSONObject;
2 | //import com.yyan.App;
3 | //import com.yyan.pojo.Block;
4 | //import org.junit.Test;
5 | //import org.junit.runner.RunWith;
6 | //import org.springframework.boot.test.context.SpringBootTest;
7 | //import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
8 | //
9 | //import java.util.ArrayList;
10 | //
11 | //
12 | //@RunWith(SpringJUnit4ClassRunner.class)
13 | //@SpringBootTest(classes = {App.class})
14 | //public class TestBlock {
15 | //
16 | //
17 | // public static ArrayList blockchain = new ArrayList<>();
18 | // public static int difficulty = 5;
19 | //
20 | // @Test
21 | // public void blockchainTest() {
22 | // //添加我们的区块到主链上
23 | //// blockchain.add(new Block("这是创世区块", "0"));
24 | //// System.out.println("正在挖掘创世区块... ");
25 | //// blockchain.get(0).mineBlock(difficulty);
26 | ////
27 | //// blockchain.add(new Block("这是第二个区块", blockchain.get(blockchain.size() - 1).hash));
28 | //// System.out.println("正在挖掘第二个区块... ... ");
29 | //// blockchain.get(1).mineBlock(difficulty);
30 | ////
31 | //// blockchain.add(new Block("这是第三个区块", blockchain.get(blockchain.size() - 1).hash));
32 | //// System.out.println("正在挖掘第三个区块... ... ");
33 | ////
34 | //// blockchain.get(2).mineBlock(difficulty);
35 | ////
36 | //// System.out.println("\n主链校验: " + isChainValid());
37 | ////
38 | //// String blockchainJson = JSONObject.toJSONString(blockchain);
39 | //// System.out.println("\n区块链: ");
40 | //// System.out.println(blockchainJson);
41 | // }
42 | //
43 | //
44 | // /**
45 | // * 检查区块链的完整性:目的是循环区块链中的所有区块并且比较hash值,
46 | // * 这个方法用来检查hash值是否是于计算出来的hash值相等,
47 | // * 同时previousHash值是否和前一个区块的hash值相等。
48 | // * 或许你会产生如下的疑问,我们就在一个主函数中创建区块链中的区块,
49 | // * 所以不存在被修改的可能性,但是你要注意的是,
50 | // * 区块链中的一个核心概念就是去中心化,
51 | // * 每一个区块可能是在网络中的某一个节点中产生的,
52 | // * 所以很有可能某个节点把自己节点中的数据修改了,
53 | // * 那么根据上述的理论数据改变会导致整个区块链的破裂,
54 | // * 也就是区块链就无效了。
55 | // *
56 | // * @return
57 | // */
58 | // public static Boolean isChainValid() {
59 | // Block currentBlock;
60 | // Block previousBlock;
61 | // String hashTarget = new String(new char[difficulty]).replace('\0', '0');
62 | //
63 | // // 循环区块链,检查hash,验证是否被篡改
64 | // for (int i = 1; i < blockchain.size(); i++) {
65 | // currentBlock = blockchain.get(i);
66 | // previousBlock = blockchain.get(i - 1);
67 | // //比较注册哈希和计算哈希
68 | // if (!currentBlock.hash.equals(currentBlock.calculateHash())) {
69 | // System.out.println("当前区块 hash 不相等");
70 | // return false;
71 | // }
72 | // //比较前hash 与 注册hash
73 | // if (!previousBlock.hash.equals(currentBlock.preHash)) {
74 | // System.out.println("前区块 hash 不相等");
75 | // return false;
76 | // }
77 | // //检查哈希是否已解决
78 | // if (!currentBlock.hash.substring(0, difficulty).equals(hashTarget)) {
79 | // System.out.println("此区块尚未挖掘");
80 | // return false;
81 | // }
82 | // }
83 | // return true;
84 | // }
85 | //
86 | //
87 | //}
88 |
--------------------------------------------------------------------------------