diff --git a/build.gradle b/build.gradle index 50aeb34..2b36477 100644 --- a/build.gradle +++ b/build.gradle @@ -7,23 +7,26 @@ plugins { } group 'cc.sukazyo' -version '0.4.0.1' +version VERSION project.ext.archiveBaseName = 'Coeur_Morny_Cono' project.ext.artifactId = 'morny-coeur' mainClassName = 'cc.sukazyo.cono.morny.ServerMain' repositories { mavenCentral() + maven { name '-ws'; url 'https://mvn.sukazyo.cc' } } dependencies { - compileOnlyApi "com.github.spotbugs:spotbugs-annotations:4.5.0" + compileOnlyApi "com.github.spotbugs:spotbugs-annotations:${libSpotbugsVersion}" - implementation 'com.github.pengrad:java-telegram-bot-api:5.4.0' + api "cc.sukazyo:messiva:${libMessivaVersion}" - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' + implementation "com.github.pengrad:java-telegram-bot-api:${libJavaTelegramBotApiVersion}" + + testImplementation "org.junit.jupiter:junit-jupiter-api:${libJunitVersion}" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${libJunitVersion}" } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..ad6e88f --- /dev/null +++ b/gradle.properties @@ -0,0 +1,13 @@ +## Core + +VERSION = 0.4.1.3 + +# dependencies + +libSpotbugsVersion = 4.5.0 + +libMessivaVersion = 0.1.0.1 + +libJavaTelegramBotApiVersion = 5.5.0 + +libJunitVersion = 5.8.2 diff --git a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java index da12eb9..9000285 100644 --- a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java +++ b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java @@ -4,6 +4,6 @@ package cc.sukazyo.cono.morny; * the final field that will be updated by gradle automatically. */ public class GradleProjectConfigures { - public static final String VERSION = "0.4.0.1"; - public static final long COMPILE_TIMESTAMP = 1638938903400L; + public static final String VERSION = "0.4.1.3"; + public static final long COMPILE_TIMESTAMP = 1639476313268L; } diff --git a/src/main/java/cc/sukazyo/cono/morny/Log.java b/src/main/java/cc/sukazyo/cono/morny/Log.java new file mode 100644 index 0000000..b58c825 --- /dev/null +++ b/src/main/java/cc/sukazyo/cono/morny/Log.java @@ -0,0 +1,18 @@ +package cc.sukazyo.cono.morny; + +import cc.sukazyo.messiva.Logger; +import cc.sukazyo.messiva.appender.ConsoleAppender; + +/** + * Morny 的 log 管理器 + */ +public class Log { + + /** + * Morny 的 Logger 实例, + * messiva 更新 + * @since 0.4.1.1 + */ + public static final Logger logger = new Logger(new ConsoleAppender()); + +} diff --git a/src/main/java/cc/sukazyo/cono/morny/Logger.java b/src/main/java/cc/sukazyo/cono/morny/Logger.java deleted file mode 100644 index f48b6d1..0000000 --- a/src/main/java/cc/sukazyo/cono/morny/Logger.java +++ /dev/null @@ -1,80 +0,0 @@ -package cc.sukazyo.cono.morny; - -import cc.sukazyo.cono.morny.util.StringUtils; - -import javax.annotation.Nonnull; - -/** - * Morny 的简单控制台 log 记录器 - */ -public class Logger { - - /** Morny 的控制台 logger 实例 */ - public static final Logger logger = new Logger(); - - /** - * [INFO] 级别的 log 消息 - * @see #formatMessage(String, String) 输出整理规则 - * @param message 消息文本,支持多行 - */ - public void info(@Nonnull String message) { - System.out.println(formatMessage(message, "INFO")); - } - - /** - * [WARN] 级别的 log 消息
- * {@link #warning(String)} 的重写 - * @see #formatMessage(String, String) 输出整理规则 - * @see #warning(String) 源方法 - * @param message 消息文本,支持多行 - */ - public void warn (@Nonnull String message) { - warning(message); - } - - /** - * [WARN] 级别的 log 消息 - * @see #formatMessage(String, String) 输出整理规则 - * @see #warn(String) 别名:warn - * @param message 消息文本,支持多行 - */ - public void warning (@Nonnull String message) { - System.out.println(formatMessage(message, "WARN")); - } - - /** - * [ERRO] 级别的 log 消息 - * @see #formatMessage(String, String) 输出整理规则 - * @param message 消息文本,支持多行 - */ - public void error (@Nonnull String message) { - System.out.println(formatMessage(message, "ERRO")); - } - - /** - * 将传入的消息和消息元数据重新整理为固定格式
- *
- * 这个方法会{@link System#currentTimeMillis() 获取当前时间}和{@link Thread#currentThread() 当前线程}的名称, - * 然后将数据整理为 {@code [][][]} 格式。
- * 如果消息是多行的,则每行的开头都会被加入 {@code [][][]} 这样的前缀, - * 不过,前缀中 {@code [][]} 会被转换为等长的 {@code '} 字串。 - *
- * 最终的 format 格式将会类似于以下的模样:

-[1019284827][EVT388223][INFO]Something message got:
-'''''''''''''''''''''''[INFO] - data source: 19773
-'''''''''''''''''''''''[INFO] - message raw: noh2q0jwd9j-jn-9jq92-ed
-	 * 
- * - * @param message 消息文本,支持多行 - * @param level log级别,考虑到对齐,推荐使用四位窄字元 - * @return 整理后的字符串 - */ - @Nonnull - private String formatMessage (@Nonnull String message, @Nonnull String level) { - final String prompt = String.format("[%s][%s]", System.currentTimeMillis(), Thread.currentThread().getName()); - final String levelStr = String.format("[%s]", level); - final String newline = "\n" + StringUtils.repeatChar('\'', prompt.length()) + levelStr; - return prompt + levelStr + message.replaceAll("\\n", newline); - } - -} diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java index 4dc90bf..c6fdf0d 100644 --- a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java +++ b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java @@ -9,11 +9,10 @@ import com.pengrad.telegrambot.request.GetMe; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import static cc.sukazyo.cono.morny.Logger.logger; +import static cc.sukazyo.cono.morny.Log.logger; /** * Morny Cono 核心
- *
* - 的程序化入口类,保管着 morny 的核心属性
*/ public class MornyCoeur { @@ -37,6 +36,11 @@ public class MornyCoeur { * 会根据这里定义的时间戳取消掉比此时间更早的事件链 */ public static long latestEventTimestamp; + /** + * morny 主程序启动时间
+ * 用于统计数据 + */ + public static final long coeurStartTimestamp = System.currentTimeMillis(); /** * bot 启动入口,执行 bot 初始化 diff --git a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java index 49074d0..89147c3 100644 --- a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java +++ b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java @@ -1,25 +1,15 @@ package cc.sukazyo.cono.morny; -import javax.annotation.Nonnull; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; +import cc.sukazyo.cono.morny.util.CommonFormatUtils; -import static cc.sukazyo.cono.morny.Logger.logger; +import javax.annotation.Nonnull; + +import static cc.sukazyo.cono.morny.Log.logger; /** * 程序启动入口
*
* 会处理程序传入的参数和选项等数据,并执行对应的启动方式
- *
- * - 第一个参数({@code args[0]})必序传递,值为 telegram-bot 的 api-token
- * - 第二个参数可选 {@code --no-hello} 和 {@code --only-hello}, - * 前者表示不输出{@link MornyHello#MORNY_PREVIEW_IMAGE_ASCII 欢迎标语}, - * 后者表示只输出{@link MornyHello#MORNY_PREVIEW_IMAGE_ASCII 欢迎标语}而不运行程序逻辑
- *
- * 或者,在第一个参数处使用 {@code --version} 来输出当前程序的版本信息 * * @since 0.4.0.0 */ @@ -120,9 +110,7 @@ public class ServerMain { MornySystem.VERSION, MornySystem.getJarMd5(), GradleProjectConfigures.COMPILE_TIMESTAMP, - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant( - Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP), - ZoneId.ofOffset("UTC", ZoneOffset.UTC))) + CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0) )); return; diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java index 73e4c1a..a7c8c5e 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java @@ -59,4 +59,8 @@ public abstract class EventListener { return false; } + public boolean onChatJoinRequest (@Nonnull Update update) { + return false; + } + } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java index 5ac91a6..343de29 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java @@ -8,7 +8,7 @@ import java.util.Arrays; import java.util.List; import java.util.function.Function; -import static cc.sukazyo.cono.morny.Logger.logger; +import static cc.sukazyo.cono.morny.Log.logger; public class EventListenerManager { @@ -93,4 +93,8 @@ public class EventListenerManager { new EventPublisher(update, x -> x.onChatMemberUpdated(update)).start(); } + public static void publishChatJoinRequestEvent (@Nonnull Update update) { + new EventPublisher(update, x -> x.onChatJoinRequest(update)).start(); + } + } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/InputCommand.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/InputCommand.java index 38e4a0b..743d0da 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/InputCommand.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/InputCommand.java @@ -37,14 +37,17 @@ public class InputCommand { return new InputCommand(cx.length == 1 ? null : cx[1], cx[0], args); } + @Nullable public String getTarget () { return target; } + @Nonnull public String getCommand () { return command; } + @Nonnull public String[] getArgs () { return args; } @@ -54,6 +57,7 @@ public class InputCommand { } @Override + @Nonnull public String toString() { return String.format("{{%s}@{%s}#{%s}}", command, target, Arrays.toString(args)); } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java index 8427283..e03653b 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java @@ -49,6 +49,9 @@ public class OnUpdate { if (update.chatMember() != null) { EventListenerManager.publishChatMemberUpdatedEvent(update); } + if (update.chatJoinRequest() != null) { + EventListenerManager.publishChatJoinRequestEvent(update); + } } return UpdatesListener.CONFIRMED_UPDATES_ALL; } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java index 8bb693b..a08e3fe 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java @@ -8,13 +8,15 @@ public class EventListeners { public static final OnActivityRecord ACTIVITY_RECORDER = new OnActivityRecord(); public static final OnUserSlashAction USER_SLASH_ACTION = new OnUserSlashAction(); public static final OnUpdateTimestampOffsetLock UPDATE_TIMESTAMP_OFFSET_LOCK = new OnUpdateTimestampOffsetLock(); + public static final OnInlineQuery INLINE_QUERY = new OnInlineQuery(); public static void registerAllListeners () { EventListenerManager.addListener( ACTIVITY_RECORDER, UPDATE_TIMESTAMP_OFFSET_LOCK, COMMANDS_LISTENER, - USER_SLASH_ACTION + USER_SLASH_ACTION, + INLINE_QUERY ); } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java index 012c56a..d3e6def 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java @@ -7,6 +7,7 @@ import cc.sukazyo.cono.morny.MornyTrusted; import cc.sukazyo.cono.morny.bot.api.EventListener; import cc.sukazyo.cono.morny.bot.api.InputCommand; import cc.sukazyo.cono.morny.bot.event.on_commands.GetUsernameAndId; +import cc.sukazyo.cono.morny.util.CommonFormatUtils; import com.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.request.ParseMode; import com.pengrad.telegrambot.request.SendMessage; @@ -14,13 +15,7 @@ import com.pengrad.telegrambot.request.SendSticker; import javax.annotation.Nonnull; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; - -import static cc.sukazyo.cono.morny.Logger.logger; +import static cc.sukazyo.cono.morny.Log.logger; public class OnCommandExecute extends EventListener { @@ -28,6 +23,7 @@ public class OnCommandExecute extends EventListener { private static final String HELLO_STICKER_ID = "CAACAgEAAxkBAAMnYYYWKNXO4ibo9dlsmDctHhhV6fIAAqooAAJ4_MYFJJhrHS74xUAiBA"; private static final String EXIT_STICKER_ID = "CAACAgEAAxkBAAMoYYYWt8UjvP0N405SAyvg2SQZmokAAkMiAAJ4_MYFw6yZLu06b-MiBA"; private static final String EXIT_403_STICKER_ID = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA"; + private static final String NON_COMMAND_QUESTION_STICKER_ID = "CAACAgEAAx0CSQh32gABA966YbRJpbmi2lCHINBDuo1DknSTsbsAAqUoAAJ4_MYFUa8SIaZriAojBA"; @Override public boolean onMessage (@Nonnull Update event) { @@ -55,12 +51,27 @@ public class OnCommandExecute extends EventListener { case "/version": onCommandVersionExec(event); break; + case "/runtime": + onCommandRuntimeExec(event); + break; default: - return false; // 无法解析的命令,转交事件链后代处理 + return nonCommandExecutable(event, command); } return true; // 命令执行成功,标记事件为已处理,退出事件链 } + private boolean nonCommandExecutable (Update event, InputCommand command) { + if (command.getTarget() == null) return false; // 无法解析的命令,转交事件链后代处理 + else { // 无法解析的显式命令格式,报错找不到命令 + MornyCoeur.getAccount().execute(new SendSticker( + event.message().chat().id(), + NON_COMMAND_QUESTION_STICKER_ID + ).replyToMessageId(event.message().messageId()) + ); + return true; + } + } + private void onCommandOnExec (@Nonnull Update event) { MornyCoeur.getAccount().execute(new SendSticker( event.message().chat().id(), @@ -101,18 +112,59 @@ public class OnCommandExecute extends EventListener { event.message().chat().id(), String.format(""" version: - %s + - %s core md5_hash: - %s + - %s compile timestamp: - %d - %s [UTC]""", + - %d + - %s [UTC]""", MornySystem.VERSION, MornySystem.getJarMd5(), GradleProjectConfigures.COMPILE_TIMESTAMP, - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant( - Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP), - ZoneId.ofOffset("UTC", ZoneOffset.UTC))) + CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0) + ) + ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML)); + } + + private void onCommandRuntimeExec (@Nonnull Update event) { + MornyCoeur.getAccount().execute(new SendMessage( + event.message().chat().id(), + String.format(""" + system: + - %s + - %s + - %d cores + java runtime: + - %s + - %s + memory: + - %d / %d MB + morny version: + - %s + - %s + - %s [UTC] + - [%d] + continuous + - %s + - [%d]""", + // system + System.getProperty("os.name"), + System.getProperty("os.version"), + Runtime.getRuntime().availableProcessors(), + // java + System.getProperty("java.vm.name"), + System.getProperty("java.version"), + // memory + Runtime.getRuntime().totalMemory() / 1024 / 1024, + Runtime.getRuntime().maxMemory() / 1024 / 1024, + // version + MornySystem.VERSION, + MornySystem.getJarMd5(), + CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0), + GradleProjectConfigures.COMPILE_TIMESTAMP, + // continuous + CommonFormatUtils.formatDuration(System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp), + System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp ) ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML)); } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQuery.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQuery.java new file mode 100644 index 0000000..6bf189e --- /dev/null +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQuery.java @@ -0,0 +1,33 @@ +package cc.sukazyo.cono.morny.bot.event; + +import cc.sukazyo.cono.morny.MornyCoeur; +import cc.sukazyo.cono.morny.bot.api.EventListener; +import cc.sukazyo.cono.morny.util.EncryptUtils; +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.model.request.InlineQueryResultArticle; +import com.pengrad.telegrambot.model.request.InputTextMessageContent; +import com.pengrad.telegrambot.model.request.ParseMode; +import com.pengrad.telegrambot.request.AnswerInlineQuery; +import org.jetbrains.annotations.NotNull; + +/** + * @since 0.4.1.3 + */ +public class OnInlineQuery extends EventListener { + + /** + * @since 0.4.1.3 + */ + @Override + public boolean onInlineQuery (@NotNull Update update) { + MornyCoeur.getAccount().execute(new AnswerInlineQuery(update.inlineQuery().id(), new InlineQueryResultArticle[]{ + new InlineQueryResultArticle( + EncryptUtils.encryptByMD5(update.inlineQuery().query()), + "Raw Input", + new InputTextMessageContent(update.inlineQuery().query()).parseMode(ParseMode.MarkdownV2) + ) + })); + return true; + } + +} diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java index 2ad2fd4..7130277 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java @@ -9,7 +9,7 @@ public class OnUpdateTimestampOffsetLock extends EventListener { @Override public boolean onMessage (@NotNull Update update) { - return update.message().date() < MornyCoeur.latestEventTimestamp*1000; + return update.message().date() < MornyCoeur.latestEventTimestamp/1000; } } diff --git a/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java b/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java index 1695a24..753944d 100644 --- a/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java +++ b/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java @@ -10,7 +10,7 @@ import java.util.HashMap; import java.util.TreeSet; import java.util.concurrent.locks.ReentrantLock; -import static cc.sukazyo.cono.morny.Logger.logger; +import static cc.sukazyo.cono.morny.Log.logger; public class TrackerDataManager { @@ -40,7 +40,7 @@ public class TrackerDataManager { } if (interrupted()) { postProcess = true; - logger.warn("last tracker write in this processor!"); + logger.info("CALLED TO EXIT! writing cache."); } if (record.size() != 0) { logger.info("start writing tracker data."); diff --git a/src/main/java/cc/sukazyo/cono/morny/util/CommonFormatUtils.java b/src/main/java/cc/sukazyo/cono/morny/util/CommonFormatUtils.java new file mode 100644 index 0000000..c629548 --- /dev/null +++ b/src/main/java/cc/sukazyo/cono/morny/util/CommonFormatUtils.java @@ -0,0 +1,28 @@ +package cc.sukazyo.cono.morny.util; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +public class CommonFormatUtils { + + public static String formatDate (long timestamp, int utcOffset) { + return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant( + Instant.ofEpochMilli(timestamp), + ZoneId.ofOffset("UTC", ZoneOffset.ofHours(utcOffset)) + )); + } + + public static String formatDuration (long duration) { + StringBuilder sb = new StringBuilder(); + if (duration > 1000 * 60 * 60 * 24) sb.append(duration / (1000*60*60*24)).append("d "); + if (duration > 1000 * 60 * 60) sb.append(duration / (1000*60*60) % 24).append("h "); + if (duration > 1000 * 60) sb.append(duration / (1000*60) % 60).append("min "); + if (duration > 1000) sb.append(duration / 1000 % 60).append("s "); + sb.append(duration % 1000).append("ms"); + return sb.toString(); + } + +} diff --git a/src/main/java/cc/sukazyo/cono/morny/util/EncryptUtils.java b/src/main/java/cc/sukazyo/cono/morny/util/EncryptUtils.java new file mode 100644 index 0000000..6d502f9 --- /dev/null +++ b/src/main/java/cc/sukazyo/cono/morny/util/EncryptUtils.java @@ -0,0 +1,61 @@ +package cc.sukazyo.cono.morny.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * 用于数据加密或编码的工具类
+ * 显然大部分代码是抄来的
+ * + */ +public class EncryptUtils { + + private final static String[] hexArray = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + + /*** + * 对指定的字符串进行MD5加密 + */ + public static String encryptByMD5(String originString) { + try { + //创建具有MD5算法的信息摘要 + MessageDigest md = MessageDigest.getInstance("MD5"); + //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 + byte[] bytes = md.digest(originString.getBytes()); + //将得到的字节数组变成字符串返回 + String s = byteArrayToHex(bytes); + return s.toUpperCase(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 将字节数组转换成十六进制,并以字符串的形式返回 + * 128位是指二进制位。二进制太长,所以一般都改写成16进制, + * 每一位16进制数可以代替4位二进制数,所以128位二进制数写成16进制就变成了128/4=32位。 + */ + private static String byteArrayToHex(byte[] b){ + StringBuilder sb = new StringBuilder(); + for (byte value : b) { + sb.append(byteToHex(value)); + } + return sb.toString(); + } + + /** + * 将一个字节转换成十六进制,并以字符串的形式返回 + */ + public static String byteToHex(byte b) { + int n = b; + if (n < 0) + n = n + 256; + int d1 = n / 16; + int d2 = n % 16; + return hexArray[d1]+hexArray[d2]; + } + +}