mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-25 04:27:41 +08:00
common 工具包改动了一些实现和补充 javadoc,并为其添加了单元测试
- Commons 工具组的一些实现改动 - _Convert.byteToHex 的实现从手动处理字母改为使用 java Integer.toHexString 方法(同时删除了私有的 hexArray 常量数组) - (WARN:breaking-changes) _Encrypt 中的命名从 encryptByX 改为 hashX - 添加了 junit 的 params 组件 (org.junit.jupiter:junit-jupiter-params) - 为 Commons 工具组的每个方法添加了其单元测试 - 单元测试添加了一个名为 MornyCLI 的执行 程序 main 方法 的程序入口包装...
This commit is contained in:
parent
063ca24bf5
commit
459470be02
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,7 +4,8 @@
|
|||||||
.vscode/
|
.vscode/
|
||||||
.gradle/
|
.gradle/
|
||||||
.settings/
|
.settings/
|
||||||
/src/test/*
|
/src/test/java/test/*
|
||||||
|
/src/test/resources/test/*
|
||||||
|
|
||||||
#build
|
#build
|
||||||
/build/
|
/build/
|
||||||
|
@ -35,6 +35,7 @@ dependencies {
|
|||||||
implementation "com.github.pengrad:java-telegram-bot-api:${libJavaTelegramBotApiVersion}"
|
implementation "com.github.pengrad:java-telegram-bot-api:${libJavaTelegramBotApiVersion}"
|
||||||
|
|
||||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${libJunitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${libJunitVersion}"
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-params:${libJunitVersion}"
|
||||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${libJunitVersion}"
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${libJunitVersion}"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
## Core
|
## Core
|
||||||
|
|
||||||
VERSION = 0.8.0.0
|
VERSION = 0.8.0.1
|
||||||
|
|
||||||
CODENAME = fuzhou
|
CODENAME = fuzhou
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ package cc.sukazyo.cono.morny;
|
|||||||
* the final field that will be updated by gradle automatically.
|
* the final field that will be updated by gradle automatically.
|
||||||
*/
|
*/
|
||||||
public class GradleProjectConfigures {
|
public class GradleProjectConfigures {
|
||||||
public static final String VERSION = "0.8.0.0";
|
public static final String VERSION = "0.8.0.1";
|
||||||
public static final String CODENAME = "fuzhou";
|
public static final String CODENAME = "fuzhou";
|
||||||
public static final long COMPILE_TIMESTAMP = 1664615965858L;
|
public static final long COMPILE_TIMESTAMP = 1664648280419L;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import com.pengrad.telegrambot.model.request.InlineQueryResultArticle;
|
|||||||
import com.pengrad.telegrambot.model.request.InputTextMessageContent;
|
import com.pengrad.telegrambot.model.request.InputTextMessageContent;
|
||||||
|
|
||||||
import static cc.sukazyo.cono.morny.util.CommonConvert.byteArrayToHex;
|
import static cc.sukazyo.cono.morny.util.CommonConvert.byteArrayToHex;
|
||||||
import static cc.sukazyo.cono.morny.util.CommonEncrypt.encryptByMD5;
|
import static cc.sukazyo.cono.morny.util.CommonEncrypt.hashMd5;
|
||||||
|
|
||||||
public class RawText implements ITelegramQuery<InlineQueryResultArticle> {
|
public class RawText implements ITelegramQuery<InlineQueryResultArticle> {
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ public class RawText implements ITelegramQuery<InlineQueryResultArticle> {
|
|||||||
public InlineQueryUnit<InlineQueryResultArticle> query (Update event) {
|
public InlineQueryUnit<InlineQueryResultArticle> query (Update event) {
|
||||||
if (event.inlineQuery().query() == null || "".equals(event.inlineQuery().query())) return null;
|
if (event.inlineQuery().query() == null || "".equals(event.inlineQuery().query())) return null;
|
||||||
return new InlineQueryUnit<>(new InlineQueryResultArticle(
|
return new InlineQueryUnit<>(new InlineQueryResultArticle(
|
||||||
ID_PREFIX + byteArrayToHex(encryptByMD5(event.inlineQuery().query())),
|
ID_PREFIX + byteArrayToHex(hashMd5(event.inlineQuery().query())),
|
||||||
TITLE,
|
TITLE,
|
||||||
new InputTextMessageContent(event.inlineQuery().query())
|
new InputTextMessageContent(event.inlineQuery().query())
|
||||||
));
|
));
|
||||||
|
@ -40,7 +40,7 @@ public class MornyJrrp {
|
|||||||
* @return 算法得到的 jrrp 值,取值为 {@code [0.00. 100.00]}
|
* @return 算法得到的 jrrp 值,取值为 {@code [0.00. 100.00]}
|
||||||
*/
|
*/
|
||||||
public static double calcJrrpXmomi (long userId, long dayStamp) {
|
public static double calcJrrpXmomi (long userId, long dayStamp) {
|
||||||
return (double)Long.parseLong(CommonConvert.byteArrayToHex(CommonEncrypt.encryptByMD5(userId + "@" + dayStamp)).substring(0, 4), 16) / (double)0xffff;
|
return (double)Long.parseLong(CommonConvert.byteArrayToHex(CommonEncrypt.hashMd5(userId + "@" + dayStamp)).substring(0, 4), 16) / (double)0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,16 @@ package cc.sukazyo.cono.morny.util;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进行简单类型转换等工作的类.
|
||||||
|
*/
|
||||||
public class CommonConvert {
|
public class CommonConvert {
|
||||||
|
|
||||||
private final static String[] hexArray = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将字节数组转换成十六进制,并以字符串的形式返回
|
* 将字节数组转换成 hex 字符串.
|
||||||
* 128位是指二进制位。二进制太长,所以一般都改写成16进制,
|
* @param b 字节数组
|
||||||
* 每一位16进制数可以代替4位二进制数,所以128位二进制数写成16进制就变成了128/4=32位。
|
* @return String 格式的字节数组的 hex 值(每个字节当中没有分隔符)
|
||||||
|
* @see #byteToHex(byte)
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String byteArrayToHex(@Nonnull byte[] b){
|
public static String byteArrayToHex(@Nonnull byte[] b){
|
||||||
@ -21,16 +23,14 @@ public class CommonConvert {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将一个字节转换成十六进制,并以字符串的形式返回
|
* 将一个字节转换成十六进制 hex 字符串.
|
||||||
|
* @param b 字节值
|
||||||
|
* @return String 格式的字节的 hex 值(小写)
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String byteToHex(byte b) {
|
public static String byteToHex(byte b) {
|
||||||
int n = b;
|
final String hex = Integer.toHexString(b & 0xff);
|
||||||
if (n < 0)
|
return hex.length()<2?"0"+hex:hex;
|
||||||
n = n + 256;
|
|
||||||
int d1 = n / 16;
|
|
||||||
int d2 = n % 16;
|
|
||||||
return hexArray[d1]+hexArray[d2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,25 @@ import java.security.MessageDigest;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于数据加密或编码的工具类<br>
|
* 用于数据加密或编解码的工具类.
|
||||||
* <s>显然大部分代码是抄来的</s><br>
|
|
||||||
* <ul>
|
|
||||||
* <li><a href="https://blog.csdn.net/yu540135101/article/details/86765457">{@link #encryptByMD5} 来源</a></li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
*/
|
||||||
public class CommonEncrypt {
|
public class CommonEncrypt {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在使用加密算法处理字符串时默认会使用的字符串编码.
|
||||||
|
* <p>
|
||||||
|
* Morny 使用 UTF-8 编码因为这是一般而言加解密工具的默认行为
|
||||||
|
*/
|
||||||
public static final Charset ENCRYPT_STANDARD_CHARSET = StandardCharsets.UTF_8;
|
public static final Charset ENCRYPT_STANDARD_CHARSET = StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/***
|
/**
|
||||||
* 对指定的字符串进行MD5加密
|
* 取得数据的 md5 散列值.
|
||||||
|
*
|
||||||
|
* @param data byte 数组形式的数据体
|
||||||
|
* @return 二进制(byte数组)格式的数据的 md5 散列值
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static byte[] encryptByMD5(@Nonnull byte[] data) {
|
public static byte[] hashMd5 (@Nonnull byte[] data) {
|
||||||
try {
|
try {
|
||||||
return MessageDigest.getInstance("md5").digest(data);
|
return MessageDigest.getInstance("md5").digest(data);
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
@ -30,9 +33,18 @@ public class CommonEncrypt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取得一个字符串的 md5 散列值.
|
||||||
|
* <p>
|
||||||
|
* 输入的字符串将会以 {@link #ENCRYPT_STANDARD_CHARSET 默认的 UTF-8} 编码进行解析
|
||||||
|
*
|
||||||
|
* @param originString 要进行散列的字符串
|
||||||
|
* @return 二进制(byte数组)格式的 md5 散列值
|
||||||
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static byte[] encryptByMD5(String originString) {
|
public static byte[] hashMd5 (String originString) {
|
||||||
return encryptByMD5(originString.getBytes(ENCRYPT_STANDARD_CHARSET));
|
return hashMd5(originString.getBytes(ENCRYPT_STANDARD_CHARSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
18
src/test/java/cc/sukazyo/cono/morny/MornyCLI.java
Normal file
18
src/test/java/cc/sukazyo/cono/morny/MornyCLI.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package cc.sukazyo.cono.morny;
|
||||||
|
|
||||||
|
import cc.sukazyo.untitled.util.command.CommonCommand;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class MornyCLI {
|
||||||
|
|
||||||
|
public static void main (String[] args) {
|
||||||
|
|
||||||
|
Scanner line = new Scanner(System.in);
|
||||||
|
System.out.print("$ java -jar morny-coeur-"+GradleProjectConfigures.VERSION+".jar" );
|
||||||
|
String x = line.nextLine();
|
||||||
|
ServerMain.main(CommonCommand.format(x));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package cc.sukazyo.cono.morny.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonConvert.byteArrayToHex;
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonConvert.byteToHex;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||||
|
|
||||||
|
public class TestCommonConvert {
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource(textBlock = """
|
||||||
|
0x00, 00
|
||||||
|
0x01, 01
|
||||||
|
0x20, 20
|
||||||
|
0x77, 77
|
||||||
|
-0x60, a0
|
||||||
|
0x0a, 0a
|
||||||
|
-0x01, ff
|
||||||
|
-0x05, fb
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
void testByteToHex(byte source, String expected) {
|
||||||
|
assertEquals(expected, byteToHex(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> testByteArrayToHexProvider () {
|
||||||
|
return Stream.of(
|
||||||
|
arguments(new byte[]{0x00}, "00"),
|
||||||
|
arguments(new byte[]{(byte)0xff}, "ff"),
|
||||||
|
arguments(new byte[]{(byte)0xc3}, "c3"),
|
||||||
|
arguments(new byte[]{}, ""),
|
||||||
|
arguments(new byte[]{0x30,0x0a,0x00,0x04,(byte)0xb0,0x00}, "300a0004b000"),
|
||||||
|
arguments(new byte[]{0x00,0x00,0x0a,(byte)0xff,(byte)0xfc,(byte)0xab,(byte)0x00,0x04}, "00000afffcab0004"),
|
||||||
|
arguments(new byte[]{0x00,0x7c,0x11,0x28,(byte)0x88,(byte)0xa6,(byte)0xfc,0x30}, "007c112888a6fc30")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("testByteArrayToHexProvider")
|
||||||
|
void testByteArrayToHex (byte[] raw, String expected) {
|
||||||
|
assertEquals(expected, byteArrayToHex(raw));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package cc.sukazyo.cono.morny.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonConvert.byteArrayToHex;
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonEncrypt.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class TestCommonEncrypt {
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@SuppressWarnings("UnnecessaryStringEscape")
|
||||||
|
@CsvSource(textBlock = """
|
||||||
|
28be57d368b75051da76c068a6733284, '莲子'
|
||||||
|
9644c5cbae223013228cd528817ba4f5, '莲子\n'
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e, ''
|
||||||
|
""")
|
||||||
|
void testHashMd5_String (String md5, String text) {
|
||||||
|
assertEquals(md5, byteArrayToHex(hashMd5(text)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package cc.sukazyo.cono.morny.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonFormat.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class TestCommonFormat {
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource(textBlock = """
|
||||||
|
1664646870402, 8, 2022-10-02 01:54:30:402
|
||||||
|
1, 8, 1970-01-01 08:00:00:001
|
||||||
|
0, -1, 1969-12-31 23:00:00:000
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
void testFormatDate (long timestamp, int utfOffset, String expectedHumanReadableTime) {
|
||||||
|
assertEquals(expectedHumanReadableTime, formatDate(timestamp, utfOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource(textBlock = """
|
||||||
|
100, '100ms'
|
||||||
|
3000, '3s 0ms'
|
||||||
|
326117522, '3d 18h 35min 17s 522ms'
|
||||||
|
53373805, 14h 49min 33s 805ms
|
||||||
|
""")
|
||||||
|
// -1, '-1ms' // WARN: maybe sometime an unexpected usage
|
||||||
|
// -194271974291, '-291ms' //
|
||||||
|
// """) //
|
||||||
|
void testFormatDuration (long durationMillis, String humanReadableDuration) {
|
||||||
|
assertEquals(humanReadableDuration, formatDuration(durationMillis));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user