mirror of
https://gitee.com/jzsw-it/yexuejc-base.git
synced 2025-12-29 21:39:25 +08:00
Compare commits
10 Commits
1415200b1a
...
1.5.3-jre1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9c65f8866 | ||
|
|
f2c904869f | ||
|
|
b0fd28d208 | ||
|
|
982f3aa418 | ||
|
|
8b43d99e11 | ||
|
|
31040ad0e9 | ||
|
|
9f5ecefc43 | ||
|
|
beb72c8009 | ||
|
|
0403c7c693 | ||
|
|
cf8231017d |
24
.gitea/workflows/package.yaml
Normal file
24
.gitea/workflows/package.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: yexuejc-base package jre11
|
||||||
|
run-name: Deploy to ${{ inputs.deploy_target }} by @${{ github.actor }} 🚀
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- jre11
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
package_job:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||||
|
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
||||||
|
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: advanced-security/maven-dependency-submission-action@v4
|
||||||
|
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||||
|
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
mvn -v
|
||||||
|
mvn clean package
|
||||||
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
10
UPDATE.md
10
UPDATE.md
@@ -2,12 +2,14 @@ yexuejc-base 更新记录
|
|||||||
------------------
|
------------------
|
||||||
|
|
||||||
#### version :1.5.3-jre11
|
#### version :1.5.3-jre11
|
||||||
**time: ** <br/>
|
**time: 2025-4-27 16:37:29** <br/>
|
||||||
**branch:** jre11 <br/>
|
**branch:** jre11 <br/>
|
||||||
**update:** <br/>
|
**update:** <br/>
|
||||||
1. [FileUtil.java](src/main/java/com/yexuejc/base/util/FileUtil.java)增加读取大文件自定义方法和单纯读取方法
|
1. [FileUtil](src/main/java/com/yexuejc/base/util/FileUtil.java) 增加读取大文件自定义方法和单纯读取方法
|
||||||
2. JsonUtil 增加objToMap;优化obj2Json
|
2. [JsonUtil](src/main/java/com/yexuejc/base/util/JsonUtil.java) 增加objToMap;优化obj2Json
|
||||||
3. DateUtil 标准化日期时间的转换函数
|
3. [DateUtil](src/main/java/com/yexuejc/base/util/DateUtil.java) 标准化日期时间的转换函数
|
||||||
|
4. [AES](src/main/java/com/yexuejc/base/encrypt/AES.java) 兼容ECB(虽然不再建议利用)
|
||||||
|
5. [StrUtil](src/main/java/com/yexuejc/base/util/StrUtil.java) 增加国家代码二进制相互转换
|
||||||
---
|
---
|
||||||
|
|
||||||
#### version :1.5.2-jre11
|
#### version :1.5.2-jre11
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>top.yexuejc</groupId>
|
<groupId>top.yexuejc</groupId>
|
||||||
<artifactId>yexuejc-base</artifactId>
|
<artifactId>yexuejc-base</artifactId>
|
||||||
<version>1.5.2-jre11</version>
|
<version>1.5.3-jre11</version>
|
||||||
|
|
||||||
<name>yexuejc-base</name>
|
<name>yexuejc-base</name>
|
||||||
<url>https://github.com/yexuejc/yexuejc-base</url>
|
<url>https://github.com/yexuejc/yexuejc-base</url>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.yexuejc.base.encrypt;
|
package com.yexuejc.base.encrypt;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES加解密
|
* AES加解密
|
||||||
@@ -35,32 +35,50 @@ public class AES {
|
|||||||
AES_CBC_NoPadding("AES/CBC/NoPadding"),
|
AES_CBC_NoPadding("AES/CBC/NoPadding"),
|
||||||
//AES/CBC/PKCS5Padding 32 16
|
//AES/CBC/PKCS5Padding 32 16
|
||||||
AES_CBC_PKCS5Padding("AES/CBC/PKCS5Padding"),
|
AES_CBC_PKCS5Padding("AES/CBC/PKCS5Padding"),
|
||||||
|
//AES/CBC/PKCS7Padding 32 16
|
||||||
|
AES_CBC_PKCS7Padding("AES/CBC/PKCS7Padding"),
|
||||||
//AES/CBC/ISO10126Padding 32 16
|
//AES/CBC/ISO10126Padding 32 16
|
||||||
AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"),
|
AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"),
|
||||||
|
//AES/CBC/ZeroPadding 16 16
|
||||||
|
AES_CBC_ZeroPadding("AES/CBC/ZeroPadding"),
|
||||||
//AES/CFB/NoPadding 16 原始数据长度
|
//AES/CFB/NoPadding 16 原始数据长度
|
||||||
AES_CFB_NoPadding("AES/CFB/NoPadding"),
|
AES_CFB_NoPadding("AES/CFB/NoPadding"),
|
||||||
//AES/CFB/PKCS5Padding 32 16
|
//AES/CFB/PKCS5Padding 16 不支持
|
||||||
AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"),
|
AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"),
|
||||||
//AES/CFB/ISO10126Padding 32 16
|
//AES/CFB/PKCS7Padding 16 不支持
|
||||||
|
AES_CFB_PKCS7Padding("AES/CFB/PKCS7Padding"),
|
||||||
|
//AES/CFB/ISO10126Padding 16 不支持
|
||||||
AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"),
|
AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"),
|
||||||
|
//AES/CFB/ZeroPadding 16 不支持
|
||||||
|
AES_CFB_ZeroPadding("AES/CFB/ZeroPadding"),
|
||||||
//AES/ECB/NoPadding 16 不支持
|
//AES/ECB/NoPadding 16 不支持
|
||||||
AES_ECB_NoPadding("AES/ECB/NoPadding"),
|
AES_ECB_NoPadding("AES/ECB/NoPadding"),
|
||||||
//AES/ECB/PKCS5Padding 32 16
|
//AES/ECB/PKCS5Padding 32 不支持
|
||||||
AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"),
|
AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"),
|
||||||
|
//AES/ECB/PKCS7Padding 32 16
|
||||||
|
AES_ECB_PKCS7Padding("AES/ECB/PKCS7Padding"),
|
||||||
//AES/ECB/ISO10126Padding 32 16
|
//AES/ECB/ISO10126Padding 32 16
|
||||||
AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"),
|
AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"),
|
||||||
|
//AES/ECB/ZeroPadding 16 16
|
||||||
|
AES_ECB_ZeroPadding("AES/ECB/ZeroPadding"),
|
||||||
//AES/OFB/NoPadding 16 原始数据长度
|
//AES/OFB/NoPadding 16 原始数据长度
|
||||||
AES_OFB_NoPadding("AES/OFB/NoPadding"),
|
AES_OFB_NoPadding("AES/OFB/NoPadding"),
|
||||||
//AES/OFB/PKCS5Padding 32 16
|
//AES/OFB/PKCS5Padding 32 16
|
||||||
AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"),
|
AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"),
|
||||||
|
//AES/OFB/PKCS7Padding 32 16
|
||||||
|
AES_OFB_PKCS7Padding("AES/OFB/PKCS7Padding"),
|
||||||
//AES/OFB/ISO10126Padding 32 16
|
//AES/OFB/ISO10126Padding 32 16
|
||||||
AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"),
|
AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"),
|
||||||
|
//AES/OFB/ZeroPadding 16 16
|
||||||
|
AES_OFB_ZeroPadding("AES/OFB/ZeroPadding"),
|
||||||
//AES/PCBC/NoPadding 16 不支持
|
//AES/PCBC/NoPadding 16 不支持
|
||||||
AES_PCBC_NoPadding("AES/PCBC/NoPadding"),
|
AES_PCBC_NoPadding("AES/PCBC/NoPadding"),
|
||||||
//AES/PCBC/PKCS5Padding 32 16
|
//AES/PCBC/PKCS5Padding 32 16
|
||||||
AES_PCBC_PKCS5Padding("AES/PCBC/PKCS5Padding"),
|
AES_PCBC_PKCS5Padding("AES/PCBC/PKCS5Padding"),
|
||||||
//AES/PCBC/ISO10126Padding 32 16
|
//AES/PCBC/ISO10126Padding 32 16
|
||||||
AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding");
|
AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding"),
|
||||||
|
//AES/CTR/NoPadding 16 不支持
|
||||||
|
AES_CTR_NoPadding("AES/CTR/NoPadding");
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
ALGORITHM(String name) {
|
ALGORITHM(String name) {
|
||||||
@@ -93,7 +111,10 @@ public class AES {
|
|||||||
byte[] plaintext = new byte[plaintextLength];
|
byte[] plaintext = new byte[plaintextLength];
|
||||||
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
|
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
|
||||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
|
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
|
||||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset));
|
IvParameterSpec ivspec = null;
|
||||||
|
if(!algorithm.name.contains("ECB")){
|
||||||
|
ivspec = new IvParameterSpec(iv.getBytes(charset));
|
||||||
|
}
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
|
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
|
||||||
byte[] encrypted = cipher.doFinal(plaintext);
|
byte[] encrypted = cipher.doFinal(plaintext);
|
||||||
return Base64.getEncoder().encodeToString(encrypted);
|
return Base64.getEncoder().encodeToString(encrypted);
|
||||||
@@ -115,7 +136,10 @@ public class AES {
|
|||||||
byte[] encrypted = Base64.getDecoder().decode(data);
|
byte[] encrypted = Base64.getDecoder().decode(data);
|
||||||
Cipher cipher = Cipher.getInstance(algorithm.name);
|
Cipher cipher = Cipher.getInstance(algorithm.name);
|
||||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
|
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
|
||||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset));
|
IvParameterSpec ivspec = null;
|
||||||
|
if(!algorithm.name.contains("ECB")){
|
||||||
|
ivspec = new IvParameterSpec(iv.getBytes(charset));
|
||||||
|
}
|
||||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||||
byte[] original = cipher.doFinal(encrypted);
|
byte[] original = cipher.doFinal(encrypted);
|
||||||
return new String(original, charset).trim();
|
return new String(original, charset).trim();
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ public class JsonUtil {
|
|||||||
/**
|
/**
|
||||||
* Json字符串转换为Java对象
|
* Json字符串转换为Java对象
|
||||||
*
|
*
|
||||||
* @param in 输入流
|
* @param in 输入流
|
||||||
* @param parametrized 容器类
|
* @param parametrized 容器类
|
||||||
* @param parameterClasses 实际类
|
* @param parameterClasses 实际类
|
||||||
* @return
|
* @return
|
||||||
@@ -347,6 +347,30 @@ public class JsonUtil {
|
|||||||
return json2Obj(obj2Json(pojo), Map.class);
|
return json2Obj(obj2Json(pojo), Map.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json -> Map<String, String> 转换
|
||||||
|
*
|
||||||
|
* @param json JSON
|
||||||
|
* @return Map
|
||||||
|
*/
|
||||||
|
public static Map<String, String> jsonToMapString(String json) {
|
||||||
|
return objToMap(json, String.class, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 Bean 对象转换为 Map
|
||||||
|
* <p>
|
||||||
|
* 示例:Map<String, RequestBean> map = JacksonMapperConfig.objToMap(data, String.class, RequestBean.class);
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param pojo Bean 数据
|
||||||
|
* @return Map 数据
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static <K, V> Map<K, V> objToMap(Object pojo, Class<K> kCls, Class<V> vCls) {
|
||||||
|
return json2Obj(obj2Json(pojo), Map.class, kCls, vCls);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化输出
|
* 格式化输出
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package com.yexuejc.base.util;
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.io.Decoders;
|
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
import io.jsonwebtoken.security.SecureDigestAlgorithm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jwt工具类
|
* jwt工具类
|
||||||
@@ -34,35 +36,46 @@ public class JwtUtil {
|
|||||||
/**
|
/**
|
||||||
* 参数配置:设置一次即可,多次设置会覆盖之前的
|
* 参数配置:设置一次即可,多次设置会覆盖之前的
|
||||||
*
|
*
|
||||||
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
* @param type 加密类型:默认JWT
|
||||||
* @param type 加密类型:默认JWT
|
* @param iss token发行商: 默认yexuejc.top
|
||||||
* @param iss token发行商: 默认yexuejc.top
|
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
||||||
|
* @param algorithm 加密方式
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static JwtUtil config(String key, String type, String iss) {
|
public static JwtUtil config(String type, String iss, String key, SecureDigestAlgorithm<SecretKey, SecretKey> algorithm) {
|
||||||
JwtUtil jwtUtil = instace();
|
JwtUtil jwtUtil = instace();
|
||||||
jwtUtil.JWT_SIGNATURE_KEY = key;
|
if (null != key) {
|
||||||
jwtUtil.JWT_HEADER_TYP = type;
|
jwtUtil.jwtSignatureKey = key;
|
||||||
jwtUtil.JWT_CLAIMS_ISS = iss;
|
}
|
||||||
|
if (null != type) {
|
||||||
|
jwtUtil.jwtHeaderTyp = type;
|
||||||
|
}
|
||||||
|
if (null != iss) {
|
||||||
|
jwtUtil.jwtClaimsIss = iss;
|
||||||
|
}
|
||||||
|
if (null != algorithm) {
|
||||||
|
jwtUtil.algorithm = algorithm;
|
||||||
|
}
|
||||||
return jwtUtil;
|
return jwtUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Instace {
|
private static class Instace {
|
||||||
private static JwtUtil jwtUtil = new JwtUtil();
|
private static JwtUtil jwtUtil = new JwtUtil();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加密用KEY
|
* 加密用KEY
|
||||||
*/
|
*/
|
||||||
private String JWT_SIGNATURE_KEY = "h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a";
|
private String jwtSignatureKey = "h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a";
|
||||||
/**
|
/**
|
||||||
* token类型
|
* token类型
|
||||||
*/
|
*/
|
||||||
private String JWT_HEADER_TYP = "JWT";
|
private String jwtHeaderTyp = "JWT";
|
||||||
/**
|
/**
|
||||||
* token发行商
|
* token发行商
|
||||||
*/
|
*/
|
||||||
private String JWT_CLAIMS_ISS = "yexuejc.top";
|
private String jwtClaimsIss = "yexuejc.top";
|
||||||
|
private SecureDigestAlgorithm<SecretKey, SecretKey> algorithm = Jwts.SIG.HS512;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加密内容生成token
|
* 加密内容生成token
|
||||||
@@ -71,27 +84,36 @@ public class JwtUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String compact(Object subjectObj) {
|
public String compact(Object subjectObj) {
|
||||||
String subject = null;
|
return compact(null, subjectObj);
|
||||||
if (subjectObj instanceof String) {
|
}
|
||||||
subject = (String) subjectObj;
|
|
||||||
} else {
|
public String compact(String subId, Object subjectObj) {
|
||||||
subject = JsonUtil.obj2Json(subjectObj);
|
String subject = subId;
|
||||||
|
Map<String, Object> subMap = JsonUtil.objToMap(subjectObj, String.class, Object.class);
|
||||||
|
if (StrUtil.isEmpty(subject)) {
|
||||||
|
if (subjectObj instanceof String) {
|
||||||
|
subject = (String) subjectObj;
|
||||||
|
} else if (StrUtil.isNotEmpty(subMap)) {
|
||||||
|
Object sid = subMap.get("subId");
|
||||||
|
Object s = subMap.get("sub");
|
||||||
|
subject = StrUtil.isNotEmpty(sid) ? String.valueOf(sid) : String.valueOf(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
// 设置token的唯一标识ID(claims.jti)
|
// 设置token的唯一标识ID(claims.jti)
|
||||||
.id(StrUtil.genUUID())
|
.id(StrUtil.genUUID())
|
||||||
// 设置token类型(header.typ)
|
// 设置token类型(header.typ)
|
||||||
.header().add("typ", JWT_HEADER_TYP)
|
.header().add("typ", jwtHeaderTyp).and()
|
||||||
.and()
|
|
||||||
// 设置token发行时间为当前时间(claims.iat)
|
// 设置token发行时间为当前时间(claims.iat)
|
||||||
.issuedAt(now)
|
.issuedAt(now).claims(JsonUtil.objToMap(subjectObj, String.class, Object.class))
|
||||||
// 设置token发行商/发行者(claims.iss)
|
// 设置token发行商/发行者(claims.iss)
|
||||||
.issuer(JWT_CLAIMS_ISS)
|
.issuer(jwtClaimsIss)
|
||||||
// 设置token用户定义主体(claims.sub)
|
// 设置token用户定义主体(claims.sub)
|
||||||
.subject(subject)
|
.subject(subject)
|
||||||
// 设置算法签名,(密钥,加密算法)
|
// 设置算法签名,(密钥,加密算法)
|
||||||
.signWith(getSecretKey(), Jwts.SIG.HS512)
|
.signWith(getSecretKey(), algorithm)
|
||||||
// 生成token
|
// 生成token
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
@@ -114,20 +136,27 @@ public class JwtUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public <T> T parse(String token, Class<T> cls) {
|
public <T> T parse(String token, Class<T> cls) {
|
||||||
return JsonUtil.json2Obj(parseStr(token), cls);
|
return JsonUtil.json2Obj(JsonUtil.obj2Json(parseStr(token)), cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解密token为字符串
|
* 解密token为字符串
|
||||||
*
|
*
|
||||||
* @param token
|
* @param token
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String parseStr(String token) {
|
public Claims parseStr(String token) {
|
||||||
return Jwts.parser().verifyWith(getSecretKey()).build().parseSignedClaims(token).getPayload().getSubject();
|
return Jwts.parser().verifyWith(getSecretKey()).build().parseSignedClaims(token).getPayload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecretKey getSecretKey() {
|
private SecretKey getSecretKey() {
|
||||||
byte[] bytes = Decoders.BASE64.decode(JWT_SIGNATURE_KEY);
|
int minLen = 32;
|
||||||
|
if (jwtSignatureKey.length() % minLen != 0) {
|
||||||
|
// 补齐32的倍数,左补0
|
||||||
|
String format = "%" + ((jwtSignatureKey.length() / minLen + 1) * minLen) + "s";
|
||||||
|
jwtSignatureKey = String.format(format, jwtSignatureKey).replace(' ', '0');
|
||||||
|
}
|
||||||
|
byte[] bytes = jwtSignatureKey.getBytes(StandardCharsets.UTF_8);
|
||||||
return Keys.hmacShaKeyFor(bytes);
|
return Keys.hmacShaKeyFor(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,7 @@ import java.lang.reflect.Array;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@@ -473,4 +465,110 @@ public final class StrUtil {
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不是空对象时执行
|
||||||
|
*
|
||||||
|
* @param checkObj 判定对象
|
||||||
|
* @param consumer 执行器
|
||||||
|
* @param <T> 判定对象
|
||||||
|
*/
|
||||||
|
public static <T> void notNullExecute(T checkObj, Consumer<T> consumer) {
|
||||||
|
if (null != checkObj) {
|
||||||
|
consumer.accept(checkObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不是空内容时执行
|
||||||
|
*
|
||||||
|
* @param checkObj 判定对象
|
||||||
|
* @param consumer 执行器
|
||||||
|
* @param <T> 判定对象
|
||||||
|
*/
|
||||||
|
public static <T> void notEmptyExecute(T checkObj, Consumer<T> consumer) {
|
||||||
|
if (isNotEmpty(checkObj)) {
|
||||||
|
consumer.accept(checkObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<String> COUNTRY_CODE = Arrays.asList("JPN", "KOR", "THA", "SGP", "CHN", "TWN", "HKG", "MAC", "999");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国名を国コードに変換
|
||||||
|
*
|
||||||
|
* @param country JPN:日本、KOR:韓国、THA:タイ、SGP:シンガポール、CHN:中国内陸、TWN:中国台湾、HKG:中国香港、MAC:マカオ、999:その他、0:不明
|
||||||
|
* @return code byte <pre>
|
||||||
|
* 1 0 1 0 1 1 1 1 1 <br>
|
||||||
|
* 日本 韓国 タイ シンガポール 中国内陸 台湾 香港 マカオ その他
|
||||||
|
* <br>
|
||||||
|
* 右→左:0位:その他、1位:マカオ、2位:香港、3位:台湾、4位:中国内陸、5位:シンガポール、6位:タイ、7位:韓国、8位:日本
|
||||||
|
* <br> 1:当該国で表示、0:当該国表示しない
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static byte countryToCodeByte(String country) {
|
||||||
|
String code = countryToCode(country);
|
||||||
|
return (byte) Integer.parseInt(code, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国家代码转換成二进制
|
||||||
|
*
|
||||||
|
* @param country JPN:日本、KOR:韓国、THA:泰国、CHN:中国内陸、SGP:新加坡、TWN:中国台湾、HKG:中国香港、MAC:中国澳门、999:其他、0:不明
|
||||||
|
* @return <pre>
|
||||||
|
* 1 0 1 0 1 1 1 1 1 <br>
|
||||||
|
* 日本 韓国 泰国 新加坡 中国内陸 台湾 香港 澳门 其他
|
||||||
|
* <br>
|
||||||
|
* 右→左:0位:其他、1位:中国澳门、2位:中国香港、3位:中国台湾、4位:中国内陸、5位:新加坡、6位:泰国、7位:韓国、8位:日本
|
||||||
|
* <br> 1:在该国表示、0:不表示该国
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static String countryToCode(String country) {
|
||||||
|
int index = COUNTRY_CODE.indexOf(country);
|
||||||
|
if (index == -1) {
|
||||||
|
return "000000000";
|
||||||
|
}
|
||||||
|
int bn = 1 << (COUNTRY_CODE.size() - 1 - index);
|
||||||
|
// 转成二进制
|
||||||
|
String bs = Integer.toBinaryString(bn);
|
||||||
|
// 为了保证长度一致,前面补0
|
||||||
|
return String.format("%09d", Integer.parseInt(bs));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国家代码二进制转国家代码
|
||||||
|
*
|
||||||
|
* @param countryCode 国家代码二进制转:010000000
|
||||||
|
* <pre>
|
||||||
|
* 1 0 1 0 1 1 1 1 1 <br>
|
||||||
|
* 日本 韓国 泰国 新加坡 中国内陸 台湾 香港 澳门 其他
|
||||||
|
* <br>
|
||||||
|
* 右→左:0位:其他、1位:中国澳门、2位:中国香港、3位:中国台湾、4位:中国内陸、5位:新加坡、6位:泰国、7位:韓国、8位:日本
|
||||||
|
* <br> 1:在该国表示、0:不表示该国
|
||||||
|
* </pre>
|
||||||
|
* @return JPN:日本、KOR:韓国、THA:泰国、CHN:中国内陸、SGP:新加坡、TWN:中国台湾、HKG:中国香港、MAC:中国澳门、999:其他、0:不明
|
||||||
|
*/
|
||||||
|
public static String getCountryByCode(String countryCode) {
|
||||||
|
int i = Integer.parseInt(countryCode, 2);
|
||||||
|
int index = Integer.numberOfTrailingZeros(i);
|
||||||
|
if (index > COUNTRY_CODE.size()) {
|
||||||
|
return "O";
|
||||||
|
}
|
||||||
|
return COUNTRY_CODE.get(COUNTRY_CODE.size() - 1 - index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nationalCodeは想定国エリア範囲内存在するかどうか
|
||||||
|
* 想定国エリア範囲:"JPN", "KOR", "THA", "SGP", "CHN", "TWN", "HKG", "MAC", "999"
|
||||||
|
*
|
||||||
|
* @param nationCode
|
||||||
|
* @return 存在:true;存在しない:false
|
||||||
|
*/
|
||||||
|
public static boolean containsCountry(String nationCode) {
|
||||||
|
if (isNotEmpty(nationCode)) {
|
||||||
|
return COUNTRY_CODE.contains(nationCode);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
55
src/test/java/com/yexuejc/base/encrypt/AESTest.java
Normal file
55
src/test/java/com/yexuejc/base/encrypt/AESTest.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package com.yexuejc.base.encrypt;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class AESTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncrypt() throws Exception {
|
||||||
|
String data = "Hello World!";
|
||||||
|
AES aes = AES.builder()
|
||||||
|
.setAlgorithm(AES.ALGORITHM.AES_CBC_PKCS5Padding)
|
||||||
|
.setKey("hj7x89H$yuBI0456")
|
||||||
|
.setIv("NIfb&95GUY86Gfgh")
|
||||||
|
.setCharset(StandardCharsets.UTF_8);
|
||||||
|
String encrypted = aes.encrypt(data);
|
||||||
|
assertNotNull(encrypted);
|
||||||
|
assertFalse(encrypted.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDecrypt() throws Exception {
|
||||||
|
String data = "p0x0vK5T6OOy69+p9cgI/9xfeoi/f0t6NO7HbLsUON4=";
|
||||||
|
AES aes = AES.builder()
|
||||||
|
.setAlgorithm(AES.ALGORITHM.AES_CBC_PKCS5Padding)
|
||||||
|
.setKey("hj7x89H$yuBI0456")
|
||||||
|
.setIv("NIfb&95GUY86Gfgh")
|
||||||
|
.setCharset(StandardCharsets.UTF_8);
|
||||||
|
String decrypted = aes.decrypt(data);
|
||||||
|
assertNotNull(decrypted);
|
||||||
|
assertFalse(decrypted.isEmpty());
|
||||||
|
assertEquals("Hello World!", decrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncryptAndDecrypt() throws Exception {
|
||||||
|
String data = "张三";
|
||||||
|
AES aes = AES.builder()
|
||||||
|
.setAlgorithm(AES.ALGORITHM.AES_OFB_ISO10126Padding)
|
||||||
|
.setKey("hj7x89H$yuBI0456")
|
||||||
|
.setIv("NIfb&95GUY86Gfgh")
|
||||||
|
.setCharset(StandardCharsets.UTF_8);
|
||||||
|
String encrypt = aes.encrypt(data);
|
||||||
|
System.out.println("加密:" + encrypt);
|
||||||
|
String decrypt = aes.decrypt(encrypt);
|
||||||
|
System.out.println("解密:" + decrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/test/java/com/yexuejc/base/util/JwtUtilTest.java
Normal file
26
src/test/java/com/yexuejc/base/util/JwtUtilTest.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author maxiaofeng
|
||||||
|
* @date 2024/9/1 15:23
|
||||||
|
*/
|
||||||
|
class JwtUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void compact() {
|
||||||
|
Map map = JsonUtil.json2Obj("{\n" + " \"payload\": {\n" + " \"sub\": \"0fqgx9h1d9eijd07umlyn1ez52jvkkkb883j\",\n" + " " +
|
||||||
|
"\"iss\": \"www" + ".donki.com\",\n" + " \"aud\": \"D27A80C9AF01488F9A1152B8C20D93BA\",\n" + " \"exp\": 1725260806," +
|
||||||
|
"\n" + " " + "\"iat\": 1725174406,\n" + " \"address\": {\n" + " \"country\": \"南朝鮮\"\n" + " },\n" + " " + "\"email_verified\": true,\n" + " \"birthdate\": \"1993/11/16\",\n" + " \"news_letter\": \"1\",\n" + " " + "\"gender\": \"other\",\n" + " \"member_code\": \"3511623793483553889787\",\n" + " \"preferred_username\": " + "\"3923490434\",\n" + " \"nonce\": \"mjhjSTmtVRNWPBtOQXZx\",\n" + " \"country_code\": \"CHN\",\n" + " " + "\"language_code\": \"zh-TW\",\n" + " \"updated_at\": 1722404351,\n" + " \"nickname\": \"3923490434\",\n" + " " + "\"customer_flag\": \"0\",\n" + " \"service_term_version\": \"2\",\n" + " \"email\": \"1828844769@qq.com\",\n" + " " + " \"auth_time\": 1725173983\n" + " }\n" + "}", Map.class);
|
||||||
|
JwtUtil jwtUtil = JwtUtil.config("JWT", "www.donki.com", "5326D79EDEF344C3B3431F268DD2564C", Jwts.SIG.HS256);
|
||||||
|
String jwtStr = jwtUtil.compact(map.get("payload"));
|
||||||
|
System.out.println(jwtStr);
|
||||||
|
|
||||||
|
Map<?, ?> parse = jwtUtil.parse(jwtStr);
|
||||||
|
System.out.println(JsonUtil.obj2Json(parse));
|
||||||
|
}
|
||||||
|
}
|
||||||
139
src/test/java/com/yexuejc/base/util/StrUtilTest.java
Normal file
139
src/test/java/com/yexuejc/base/util/StrUtilTest.java
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class StrUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isEmpty() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isNotEmpty() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void genUUID() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGenUUID() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void genNum() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toHex() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toMD5() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toSHA256() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toSHA() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void iso2utf() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isNumeric() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void codeId() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void decodeId() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parseUrlencoded() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSignContent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void replaceMobile() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mapSort() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void setStr() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void underlineToCamel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void camelToUnderline() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void printStackTraceAndMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void printStackTrace() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void notNullExecute() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void notEmptyExecute() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void countryToCode() {
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("JPN"), "100000000");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("KOR"), "010000000");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("THA"), "001000000");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("SGP"), "000100000");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("CHN"), "000010000");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("TWN"), "000001000");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("HKG"), "000000100");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("MAC"), "000000010");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("999"), "000000001");
|
||||||
|
Assertions.assertEquals(StrUtil.countryToCode("O"), "000000000");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getCountryByCode() {
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("100000000"), "JPN");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("010000000"), "KOR");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("001000000"), "THA");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000100000"), "SGP");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000010000"), "CHN");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000001000"), "TWN");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000000100"), "HKG");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000000010"), "MAC");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000000001"), "999");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("000000000"), "O");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("100000000000"), "O");
|
||||||
|
Assertions.assertEquals(StrUtil.getCountryByCode("-100000000000"), "O");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void countryToCodeByte() {
|
||||||
|
System.out.println(String.format("%9s", Integer.toBinaryString(StrUtil.countryToCodeByte("CHN") & 0xFF)).replace(" ", "0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user