From e2e032644a973d46b62079add2026694090fb68c Mon Sep 17 00:00:00 2001 From: xuxueli <931591021@qq.com> Date: Sun, 15 Dec 2024 22:23:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=9A=E4=B8=AA=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=8C=85=E6=8B=AC?= =?UTF-8?q?=EF=BC=9AMd5Tool=E3=80=81HexTool=20=E7=AD=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...30\346\226\271\346\226\207\346\241\243.md" | 3 + .../java/com/xxl/tool/encrypt/HexTool.java | 135 ++++++++++++++++++ .../java/com/xxl/tool/encrypt/Md5Tool.java | 53 +++++++ .../xxl/tool/test/encrypt/HexToolTest.java | 24 ++++ .../xxl/tool/test/encrypt/Md5ToolTest.java | 19 +++ 5 files changed, 234 insertions(+) create mode 100644 src/main/java/com/xxl/tool/encrypt/HexTool.java create mode 100644 src/main/java/com/xxl/tool/encrypt/Md5Tool.java create mode 100644 src/test/java/com/xxl/tool/test/encrypt/HexToolTest.java create mode 100644 src/test/java/com/xxl/tool/test/encrypt/Md5ToolTest.java diff --git "a/doc/XXL-TOOL\345\256\230\346\226\271\346\226\207\346\241\243.md" "b/doc/XXL-TOOL\345\256\230\346\226\271\346\226\207\346\241\243.md" index b74ec2b..a155219 100644 --- "a/doc/XXL-TOOL\345\256\230\346\226\271\346\226\207\346\241\243.md" +++ "b/doc/XXL-TOOL\345\256\230\346\226\271\346\226\207\346\241\243.md" @@ -428,6 +428,9 @@ logger.info(text); - 3、【完善】工具类单测完善; - 4、【升级】升级依赖版本,如slf4j、poi、spring、gson…等。 +### 3.7 v1.3.2 Release Notes[迭代中] +- 1、【新增】新增多个工具类模块,包括:Md5Tool、HexTool 等; + ### TODO LIST - excel模块:大数据导出,流式导入导出; diff --git a/src/main/java/com/xxl/tool/encrypt/HexTool.java b/src/main/java/com/xxl/tool/encrypt/HexTool.java new file mode 100644 index 0000000..3f49f59 --- /dev/null +++ b/src/main/java/com/xxl/tool/encrypt/HexTool.java @@ -0,0 +1,135 @@ +package com.xxl.tool.encrypt; + +import java.nio.charset.StandardCharsets; + +/** + * hex tool + * + * @author xuxueli 2024-12-15 + */ +public final class HexTool { + + // ---------------------- constants ---------------------- + + /** + * Table for HEX to DEC byte translation. + */ + private static final int[] DEC = { 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, + 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, }; + + + /** + * Table for DEC to HEX byte translation. + */ + private static final byte[] HEX = + { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' }; + + + /** + * Table for byte to hex string translation. + */ + private static final char[] hex = "0123456789abcdef".toCharArray(); + + + // ---------------------- Static Methods ---------------------- + + public static int getDec(int index) { + // Fast for correct values, slower for incorrect ones + try { + return DEC[index - '0']; + } catch (ArrayIndexOutOfBoundsException ex) { + return -1; + } + } + + + public static byte getHex(int index) { + return HEX[index]; + } + + + public static String toHexString(char c) { + // 2 bytes / 4 hex digits + StringBuilder sb = new StringBuilder(4); + + sb.append(hex[(c & 0xf000) >> 12]); + sb.append(hex[(c & 0x0f00) >> 8]); + + sb.append(hex[(c & 0xf0) >> 4]); + sb.append(hex[(c & 0x0f)]); + + return sb.toString(); + } + + + // ---------------------- tool ---------------------- + + /** + * byte to hex + * + * @param input + * @return + */ + public static String toHex(String input) { + return byteToHex(input.getBytes(StandardCharsets.UTF_8)); + } + /** + * byte to hex + * + * @param bytes + * @return + */ + public static String byteToHex(byte[] bytes) { + if (null == bytes) { + return null; + } + + StringBuilder sb = new StringBuilder(bytes.length << 1); + for (byte aByte : bytes) { + sb.append(hex[(aByte & 0xf0) >> 4]).append(hex[(aByte & 0x0f)]); + } + + return sb.toString(); + } + + /** + * hex to byte + * + * @param input + * @return + */ + public static String fromHex(String input) { + return new String(hexToByte(input), StandardCharsets.UTF_8); + } + + /** + * hex to byte + * + * @param input + * @return + */ + public static byte[] hexToByte(String input) { + if (input == null) { + return null; + } + + if ((input.length() & 1) == 1) { + throw new IllegalArgumentException("Odd number of characters"); + } + + char[] inputChars = input.toCharArray(); + byte[] result = new byte[input.length() >> 1]; + for (int i = 0; i < result.length; i++) { + int upperNibble = getDec(inputChars[2 * i]); + int lowerNibble = getDec(inputChars[2 * i + 1]); + if (upperNibble < 0 || lowerNibble < 0) { + throw new IllegalArgumentException("None hex character"); + } + result[i] = (byte) ((upperNibble << 4) + lowerNibble); + } + return result; + } + +} diff --git a/src/main/java/com/xxl/tool/encrypt/Md5Tool.java b/src/main/java/com/xxl/tool/encrypt/Md5Tool.java new file mode 100644 index 0000000..4c7dcf8 --- /dev/null +++ b/src/main/java/com/xxl/tool/encrypt/Md5Tool.java @@ -0,0 +1,53 @@ +package com.xxl.tool.encrypt; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +/** + * md5 tool + * + * @author xuxueli 2024-12-15 + */ +public abstract class Md5Tool { + + private static final String MD5_ALGORITHM_NAME = "MD5"; + + private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + /** + * calculate md5 for input + * + * @param input + * @return + */ + public static String md5(String input) { + return md5(input.getBytes(StandardCharsets.UTF_8)); + } + + /** + * calculate md5 for input + * + * @param input 输入字节数组 + * @return MD5摘要的十六进制字符串 + */ + public static String md5(byte[] input) { + try { + MessageDigest md = MessageDigest.getInstance(MD5_ALGORITHM_NAME); + byte[] digest = md.digest(input); + return HexTool.byteToHex(digest); + } catch (Exception e) { + throw new IllegalStateException("Md5Tool#md5 error, input:"+ input, e); + } + } + + /*private static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int i = 0; i < bytes.length; i++) { + int v = bytes[i] & 0xFF; + hexChars[i * 2] = HEX_CHARS[v >>> 4]; + hexChars[i * 2 + 1] = HEX_CHARS[v & 0x0F]; + } + return new String(hexChars); + }*/ + +} diff --git a/src/test/java/com/xxl/tool/test/encrypt/HexToolTest.java b/src/test/java/com/xxl/tool/test/encrypt/HexToolTest.java new file mode 100644 index 0000000..63199d8 --- /dev/null +++ b/src/test/java/com/xxl/tool/test/encrypt/HexToolTest.java @@ -0,0 +1,24 @@ +package com.xxl.tool.test.encrypt; + +import com.xxl.tool.encrypt.HexTool; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HexToolTest { + private static Logger logger = LoggerFactory.getLogger(HexToolTest.class); + + @Test + public void test(){ + String input = "xxl-tool"; + String output = HexTool.toHex(input); + logger.info("input: {}, output: {}", input, output); + + String input2 = HexTool.fromHex(output); + logger.info("calculate input2: {}", input2); + + Assertions.assertEquals(input, input2); + } + +} diff --git a/src/test/java/com/xxl/tool/test/encrypt/Md5ToolTest.java b/src/test/java/com/xxl/tool/test/encrypt/Md5ToolTest.java new file mode 100644 index 0000000..545da6a --- /dev/null +++ b/src/test/java/com/xxl/tool/test/encrypt/Md5ToolTest.java @@ -0,0 +1,19 @@ +package com.xxl.tool.test.encrypt; + +import com.xxl.tool.encrypt.Md5Tool; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Md5ToolTest { + private static Logger logger = LoggerFactory.getLogger(Md5ToolTest.class); + + @Test + public void test(){ + String input = "test"; + + String output = Md5Tool.md5(input); + logger.info("input:{}, md5:{}", input, output); + } + +}