From 1efd3cd6634dde15af6a981de5dbaa9927f110a8 Mon Sep 17 00:00:00 2001 From: jianjun Date: Fri, 22 Apr 2022 17:20:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/tools/utils/AuthCodeUtil.java | 389 ++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/AuthCodeUtil.java diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/AuthCodeUtil.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/AuthCodeUtil.java new file mode 100644 index 0000000000..0ca2ab6412 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/AuthCodeUtil.java @@ -0,0 +1,389 @@ +package com.epmet.commons.tools.utils; + +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; + +/** + * desc: 市北大数据局的工具 + * + * @return + * @author LiuJanJun + * @date 2022/4/22 5:19 下午 + */ +@Slf4j +public class AuthCodeUtil { + + public enum DiscuzAuthcodeMode { + Encode, Decode + } + + /** + * + * 从字符串的指定位置截取指定长度的子字符串 + * + * 原字符串 + * 子字符串的起始位置 + * 子字符串的长度 + * 子字符串 + */ + public static String CutString(String str, int startIndex, int length) { + if (startIndex >= 0) { + if (length < 0) { + length = length * -1; + if (startIndex - length < 0) { + length = startIndex; + startIndex = 0; + } else { + startIndex = startIndex - length; + } + } + + if (startIndex > str.length()) { + return ""; + } + + } else { + if (length < 0) { + return ""; + } else { + if (length + startIndex > 0) { + length = length + startIndex; + startIndex = 0; + } else { + return ""; + } + } + } + + if (str.length() - startIndex < length) { + + length = str.length() - startIndex; + } + + return str.substring(startIndex, startIndex + length); + } + + /** + * + * 从字符串的指定位置开始截取到字符串结尾的了符串 + * + * 原字符串 + * 子字符串的起始位置 + * 子字符串 + */ + public static String CutString(String str, int startIndex) { + return CutString(str, startIndex, str.length()); + } + + /** + * + * 返回文件是否存在 + * + * 文件名 + * 是否存在 + */ + public static boolean FileExists(String filename) { + File f = new File(filename); + return f.exists(); + } + + /** + * + * MD5函数 + * + * 原始字符串 + * MD5结果 + */ + public static String MD5(String str) { + StringBuffer sb = new StringBuffer(); + String part = null; + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] md5 = md.digest(str.getBytes()); + + for (int i = 0; i < md5.length; i++) { + part = Integer.toHexString(md5[i] & 0xFF); + if (part.length() == 1) { + part = "0" + part; + } + sb.append(part); + } + + } catch (NoSuchAlgorithmException ex) { + } + return sb.toString(); + } + + /** + * + * 字段串是否为Null或为""(空) + * + * + * + */ + public static boolean StrIsNullOrEmpty(String str) { + // if NET1 + if (str == null || str.trim().equals("")) { + return true; + } + + return false; + } + + /** + * + * 用于 RC4 处理密码 + * + * 密码字串 + * 密钥长度,一般为 256 + * + */ + static private byte[] GetKey(byte[] pass, int kLen) { + byte[] mBox = new byte[kLen]; + + for (int i = 0; i < kLen; i++) { + mBox[i] = (byte) i; + } + + int j = 0; + for (int i = 0; i < kLen; i++) { + + j = (j + (int) ((mBox[i] + 256) % 256) + pass[i % pass.length]) + % kLen; + + byte temp = mBox[i]; + mBox[i] = mBox[j]; + mBox[j] = temp; + } + + return mBox; + } + + /** + * + * 生成随机字符 + * + * 随机字符长度 + * 随机字符 + */ + public static String RandomString(int lens) { + char[] CharArray = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + int clens = CharArray.length; + String sCode = ""; + Random random = new Random(); + for (int i = 0; i < lens; i++) { + sCode += CharArray[Math.abs(random.nextInt(clens))]; + } + return sCode; + } + + /** + * + * 使用 Discuz authcode 方法对字符串加密 + * + * 原始字符串 + * 密钥 + * 加密字串有效时间,单位是秒 + * 加密结果 + */ + public static String authcodeEncode(String source, String key, int expiry) { + return authcode(source, key, DiscuzAuthcodeMode.Encode, expiry); + + } + + /** + * + * 使用 Discuz authcode 方法对字符串加密 + * + * 原始字符串 + * 密钥 + * 加密结果 + */ + public static String authcodeEncode(String source, String key) { + return authcode(source, key, DiscuzAuthcodeMode.Encode, 0); + + } + + /** + * + * 使用 Discuz authcode 方法对字符串解密 + * + * 原始字符串 + * 密钥 + * 解密结果 + */ + public static String authcodeDecode(String source, String key) { + return authcode(source, key, DiscuzAuthcodeMode.Decode, 0); + + } + + /** + * + * 使用 变形的 rc4 编码方法对字符串进行加密或者解密 + * + * 原始字符串 + * 密钥 + * 操作 加密还是解密 + * 加密字串过期时间 + * 加密或者解密后的字符串 + */ + private static String authcode(String source, String key, + DiscuzAuthcodeMode operation, int expiry) { + try { + if (source == null || key == null) { + return ""; + } + + int ckey_length = 4; + String keya, keyb, keyc, cryptkey, result; + + key = MD5(key); + + keya = MD5(CutString(key, 0, 16)); + + keyb = MD5(CutString(key, 16, 16)); + + keyc = ckey_length > 0 ? (operation == DiscuzAuthcodeMode.Decode ? CutString( + source, 0, ckey_length) : RandomString(ckey_length)) + : ""; + + cryptkey = keya + MD5(keya + keyc); + + if (operation == DiscuzAuthcodeMode.Decode) { + byte[] temp; + + temp = Base64.getDecoder().decode(CutString(source, ckey_length)); + result = new String(RC4(temp, cryptkey)); + if (CutString(result, 10, 16).equals( + CutString(MD5(CutString(result, 26) + keyb), 0, 16))) { + return CutString(result, 26); + } else { + temp = Base64.getDecoder().decode(CutString(source + "=", ckey_length)); + result = new String(RC4(temp, cryptkey)); + if (CutString(result, 10, 16) + .equals(CutString( + MD5(CutString(result, 26) + keyb), 0, 16))) { + return CutString(result, 26); + } else { + temp = Base64.getDecoder().decode(CutString(source + "==", + ckey_length)); + result = new String(RC4(temp, cryptkey)); + if (CutString(result, 10, 16).equals( + CutString(MD5(CutString(result, 26) + keyb), 0, + 16))) { + return CutString(result, 26); + } else { + return "2"; + } + } + } + } else { + source = "0000000000" + CutString(MD5(source + keyb), 0, 16) + + source; + + byte[] temp = RC4(source.getBytes("GBK"), cryptkey); + + return keyc + Base64.getEncoder().encode(temp); + + } + } catch (Exception e) { + return ""; + } + + } + + /** + * + * RC4 原始算法 + * + * 原始字串数组 + * 密钥 + * 处理后的字串数组 + */ + private static byte[] RC4(byte[] input, String pass) { + if (input == null || pass == null) + return null; + + byte[] output = new byte[input.length]; + byte[] mBox = GetKey(pass.getBytes(), 256); + + // 加密 + int i = 0; + int j = 0; + + for (int offset = 0; offset < input.length; offset++) { + i = (i + 1) % mBox.length; + j = (j + (int) ((mBox[i] + 256) % 256)) % mBox.length; + + byte temp = mBox[i]; + mBox[i] = mBox[j]; + mBox[j] = temp; + byte a = input[offset]; + + // byte b = mBox[(mBox[i] + mBox[j] % mBox.Length) % mBox.Length]; + // mBox[j] 一定比 mBox.Length 小,不需要在取模 + byte b = mBox[(toInt(mBox[i]) + toInt(mBox[j])) % mBox.length]; + + output[offset] = (byte) ((int) a ^ (int) toInt(b)); + } + + return output; + } + + public static int toInt(byte b) { + return (int) ((b + 256) % 256); + } + + public long getUnixTimestamp() { + Calendar cal = Calendar.getInstance(); + return cal.getTimeInMillis() / 1000; + } + + public static void main(String[] args) throws IOException { + getStr(); + //readFile02("/Users/liujianjun/Downloads/abc.txt"); + } + + + /** + * 读取一个文本 一行一行读取 + * + * @param path + * @return + * @throws IOException + */ + private static void readFile02(String path) throws IOException { + // 使用一个字符串集合来存储文本中的路径 ,也可用String []数组 + List list = new ArrayList(); + FileInputStream fis = new FileInputStream(path); + // 防止路径乱码 如果utf-8 乱码 改GBK eclipse里创建的txt 用UTF-8,在电脑上自己创建的txt 用GBK + InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8); + BufferedReader br = new BufferedReader(isr); + String line = ""; + String result = null; + while ((line = br.readLine()) != null) { + String key = "TvFwHe6tGA"; + result = AuthCodeUtil.authcodeDecode(line, key); + System.out.println(result); + } + br.close(); + isr.close(); + fis.close(); + System.out.println("==========end"); + } + + private static void getStr(){ + String tel = "4fb1lYySlVqMUaf/LnlBEM1nDZgCKnX+Q52azUGgSLCV0hioBvLFFZoJS1Vu"; + tel = "a1孙1增勤"; + String result = AuthCodeUtil.authcodeDecode(tel, "TvFwHe6tGA"); + System.out.println(result); + } + +}