🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄
🌹简历模板、学习资料、面试题库、技术互助
🌹文末获取联系方式 📝
往期热门专栏回顾
专栏 | 描述 |
---|
Java项目实战 | 介绍Java组件安装、使用;手写框架等 |
Aws服务器实战 | Aws Linux服务器上操作nginx、git、JDK、Vue |
Java微服务实战 | Java 微服务实战,Spring Cloud Netflix套件、Spring Cloud Alibaba套件、Seata、gateway、shadingjdbc等实战操作 |
Java基础篇 | Java基础闲聊,已出HashMap、String、StringBuffer等源码分析,JVM分析,持续更新中 |
Springboot篇 | 从创建Springboot项目,到加载数据库、静态资源、输出RestFul接口、跨越问题解决到统一返回、全局异常处理、Swagger文档 |
Spring MVC篇 | 从创建Spring MVC项目,到加载数据库、静态资源、输出RestFul接口、跨越问题解决到统一返回 |
华为云服务器实战 | 华为云Linux服务器上操作nginx、git、JDK、Vue等,以及使用宝塔运维操作添加Html网页、部署Springboot项目/Vue项目等 |
Java爬虫 | 通过Java+Selenium+GoogleWebDriver 模拟真人网页操作爬取花瓣网图片、bing搜索图片等 |
Vue实战 | 讲解Vue3的安装、环境配置,基本语法、循环语句、生命周期、路由设置、组件、axios交互、Element-ui的使用等 |
Spring | 讲解Spring(Bean)概念、IOC、AOP、集成jdbcTemplate/redis/事务等 |
前言
俗话说得好,好记性不如烂笔头,尤其是互联网工作项目流动性大,每个人可能管理好几个甚至十多个项目,电脑也是人手好几台,这时候一些工具类就需要记录下来,在我们需要时,及时的拿出来。
HexUtil
直接使用JDK8即可,不需要额外的jar包。
import java.io.UnsupportedEncodingException;
public class HexUtil {
public static void main(String[] args) throws UnsupportedEncodingException {
String hexString = "3058 4645 2030 5846 4520 3058 4645 2030 5846 4520 3058 3731";
System.out.println( new String(HexUtil.HexStringToByte(hexString) , "UTF-8") );
}
/**
* 16进制字符串转换为Byte型数组16进制源字符串
*
* @param hexString 16进制字符串
* @return Byte类型数组
*/
public static byte[] HexStringToByte(String hexString) {
hexString = hexString.replace(" ", "");
int len = hexString.length();
if (len % 2 != 0)
return null;
byte[] bufD = new byte[len / 2];
byte[] tmpBuf = hexString.getBytes();
int i = 0, j = 0;
for (i = 0; i < len; i++) {
if (tmpBuf[i] >= 0x30 && tmpBuf[i] <= 0x39)
tmpBuf[i] -= 0x30;
else if (tmpBuf[i] >= 0x41 && tmpBuf[i] <= 0x46)
tmpBuf[i] -= 0x37;
else if (tmpBuf[i] >= 0x61 && tmpBuf[i] <= 0x66)
tmpBuf[i] -= 0x57;
else
tmpBuf[i] = 0xF;
}
for (i = 0, j = 0; i < len; i += 2, j++) {
bufD[j] = (byte) ((tmpBuf[i] << 4) | tmpBuf[i + 1]);
}
return bufD;
}
}
HmacUtil
Hmac的Java实现,加入了HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512。
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.Mac;
@Slf4j
public class HmacUtil {
public static enum Algorithm {
HMAC_MD5("HmacMD5"),
HMAC_SHA1("HmacSHA1"),
HMAC_SHA256("HmacSHA256"),
HMAC_SHA384("HmacSHA384"),
HMAC_SHA512("HmacSHA512");
private String value;
Algorithm(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public final static String APP_SECRET = "seelook";
public static void main(String[] args) {
String message = "Hello, World!";
try {
log.info("HMAC-SHA512 length:{} info:{}", HmacUtil.getHmacSHA512Data(message).length(), HmacUtil.getHmacSHA512Data(message));
log.info("HMAC-SHA384 length:{} info:{}", HmacUtil.getHmacSHA384Data(message).length(), HmacUtil.getHmacSHA384Data(message));
log.info("HMAC-SHA256 length:{} info:{}", HmacUtil.getHmacSHA256Data(message).length(), HmacUtil.getHmacSHA256Data(message));
log.info("HMAC-SHA1 length:{} info:{}", HmacUtil.getHmacSHA1Data(message).length(), HmacUtil.getHmacSHA1Data(message));
log.info("HMAC-MD5 length:{} info:{}", HmacUtil.getHmacMD5Data(message).length(), HmacUtil.getHmacMD5Data(message));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
public static String getHmacSHA512Data(String data) throws NoSuchAlgorithmException, InvalidKeyException {
String instance = Algorithm.HMAC_SHA512.value;
return getHmacData(data, instance);
}
public static String getHmacSHA256Data(String data) throws NoSuchAlgorithmException, InvalidKeyException {
String instance = Algorithm.HMAC_SHA256.value;
return getHmacData(data, instance);
}
public static String getHmacSHA1Data(String data) throws NoSuchAlgorithmException, InvalidKeyException {
String instance = Algorithm.HMAC_SHA1.value;
return getHmacData(data, instance);
}
public static String getHmacMD5Data(String data) throws NoSuchAlgorithmException, InvalidKeyException {
String instance = Algorithm.HMAC_MD5.value;
return getHmacData(data, instance);
}
public static String getHmacSHA384Data(String data) throws NoSuchAlgorithmException, InvalidKeyException {
String instance = Algorithm.HMAC_SHA384.value;
return getHmacData(data, instance);
}
private static String getHmacData(String data, String instance) throws NoSuchAlgorithmException, InvalidKeyException {
// 生成密钥
SecretKey secretKey = new SecretKeySpec(APP_SECRET.getBytes(), instance);
// 创建HMAC-SHA256的Mac实例
Mac mac = Mac.getInstance(instance);
// 初始化Mac实例,并设置密钥
mac.init(secretKey);
// 计算认证码
byte[] hmac = mac.doFinal(data.getBytes());
return bytesToHex(hmac);
}
private static SecretKey generateSecretKey(String instance) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(instance);
return keyGenerator.generateKey();
}
public static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}
单机雪花算法SnowflakeIdWorker
分布式下可考虑加入redis自增数,来解决多服务器ID相同问题。
public class SnowflakeCommon {
public static volatile SnowflakeIdWorker idWorker = null;
public static synchronized SnowflakeIdWorker getIdWorker() {
if (null == idWorker) {
idWorker = new SnowflakeIdWorker(0, 0);
}
return idWorker;
}
}
public class SnowflakeIdWorker {
/**
* 开始时间截 (2015-01-01)
*/
private final long twepoch = 1420041600000L;
/**
* 机器id所占的位数
*/
private final long workerIdBits = 5L;
/**
* 数据标识id所占的位数
*/
private final long datacenterIdBits = 5L;
/**
* 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
*/
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
/**
* 支持的最大数据标识id,结果是31
*/
private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
/**
* 序列在id中占的位数
*/
private final long sequenceBits = 12L;
/**
* 机器ID向左移12位
*/
private final long workerIdShift = sequenceBits;
/**
* 数据标识id向左移17位(12+5)
*/
private final long datacenterIdShift = sequenceBits + workerIdBits;
/**
* 时间截向左移22位(5+5+12)
*/
private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
/**
* 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
*/
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
/**
* 工作机器ID(0~31)
*/
private long workerId;
/**
* 数据中心ID(0~31)
*/
private long datacenterId;
/**
* 毫秒内序列(0~4095)
*/
private long sequence = 0L;
/**
* 上次生成ID的时间截
*/
private long lastTimestamp = -1L;
/**
* 构造函数
* @param workerId 工作ID (0~31)
* @param datacenterId 数据中心ID (0~31)
*/
public SnowflakeIdWorker(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* 获得下一个ID (该方法是线程安全的)
* @return SnowflakeId
*/
public synchronized long nextId() {
long timestamp = timeGen();
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
if (timestamp < lastTimestamp) {
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
// 如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
// 毫秒内序列溢出
if (sequence == 0) {
//阻塞到下一个毫秒,获得新的时间戳
timestamp = tilNextMillis(lastTimestamp);
}
}
// 时间戳改变,毫秒内序列重置
else {
sequence = 0L;
}
// 上次生成ID的时间截
lastTimestamp = timestamp;
// 移位并通过或运算拼到一起组成64位的ID
return ((timestamp - twepoch) << timestampLeftShift) //
| (datacenterId << datacenterIdShift) //
| (workerId << workerIdShift) //
| sequence;
}
/**
* 阻塞到下一个毫秒,直到获得新的时间戳
* @param lastTimestamp 上次生成ID的时间截
* @return 当前时间戳
*/
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
/**
* 返回以毫秒为单位的当前时间
* @return 当前时间(毫秒)
*/
protected long timeGen() {
return System.currentTimeMillis();
}
}
redis工具类
基于spring和redis的redisTemplate工具类,JSON序列化采用fastjson,可自行替换。
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* 基于spring和redis的redisTemplate工具类
*
* 针对所有的hash 都是以h开头的方法
* 针对所有的Set 都是以s开头的方法 不含通用方法
* 针对所有的List 都是以l开头的方法
*
*/
@Component
@Slf4j
public class RedisUtil {
@Resource
private RedisTemplate redisTemplate;
// =============================common============================
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection) CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 批量获取普通缓存(根据前缀模糊匹配)
*/
public List
资料获取,更多粉丝福利,关注下方公众号获取