This commit is contained in:
Looly 2023-01-15 12:00:23 +08:00
parent d5e8c53b2b
commit 9261511574
13 changed files with 1463 additions and 255 deletions

View File

@ -31,7 +31,11 @@ public class HexUtil {
* @return 是否为16进制
*/
public static boolean isHexNumber(final String value) {
int index = (value.startsWith("-") ? 1 : 0);
if(StrUtil.startWith(value, '-')){
// issue#2875
return false;
}
int index = 0;
if (value.startsWith("0x", index) || value.startsWith("0X", index)) {
index += 2;
} else if (value.startsWith("#", index)) {

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ import cn.hutool.core.text.StrUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
@ -17,96 +18,11 @@ import java.util.concurrent.ConcurrentSkipListMap;
*
* <p>需要注意的是xlsxdocx等Office2007格式全部识别为zip因为新版采用了OpenXML格式这些格式本质上是XML文件打包为zip</p>
*
* TODO 参考https://github.com/sindresorhus/file-type/blob/main/core.js 重构此工具
*
* @author Looly
*/
public class FileTypeUtil {
private static final Map<String, String> FILE_TYPE_MAP;
static {
FILE_TYPE_MAP = new ConcurrentSkipListMap<>((s1, s2) -> {
final int len1 = s1.length();
final int len2 = s2.length();
if (len1 == len2) {
return s1.compareTo(s2);
} else {
return len2 - len1;
}
});
// 2-byte signatures
// https://github.com/sindresorhus/file-type/blob/main/core.js#L90
FILE_TYPE_MAP.put("424D", "bmp"); // 位图(bmp)
FILE_TYPE_MAP.put("0B77", "ac3");
FILE_TYPE_MAP.put("7801", "dmg");
FILE_TYPE_MAP.put("4D5A", "exe");
FILE_TYPE_MAP.put("1FA0", "Z");
FILE_TYPE_MAP.put("1F9D", "Z");
// 3-byte signatures
// https://github.com/sindresorhus/file-type/blob/main/core.js#L149
FILE_TYPE_MAP.put("474946", "gif"); // GIF (gif)
FILE_TYPE_MAP.put("FFd8FF", "jpg"); // JPEG (jpg)
FILE_TYPE_MAP.put("4949BC", "jxr"); // jxr
FILE_TYPE_MAP.put("1F8B08", "gz"); // gzip
FILE_TYPE_MAP.put("425A68", "bz2"); // bz2
// check string
FILE_TYPE_MAP.put(HexUtil.encodeHexStr("MP+"), "mpc");
FILE_TYPE_MAP.put(HexUtil.encodeHexStr("FLIF"), "flif");
FILE_TYPE_MAP.put(HexUtil.encodeHexStr("8BPS"), "psd");// Photoshop (psd)
FILE_TYPE_MAP.put(HexUtil.encodeHexStr("MPCK"), "mpc");
FILE_TYPE_MAP.put(HexUtil.encodeHexStr("FORM"), "aif");// Musepack, SV8
FILE_TYPE_MAP.put(HexUtil.encodeHexStr("icns"), "icns");
FILE_TYPE_MAP.put("89504e47", "png"); // PNG (png)
FILE_TYPE_MAP.put("49492a00227105008037", "tif"); // TIFF (tif)
FILE_TYPE_MAP.put("41433130313500000000", "dwg"); // CAD (dwg)
FILE_TYPE_MAP.put("7b5c727466315c616e73", "rtf"); // Rich Text Format (rtf)
FILE_TYPE_MAP.put("46726f6d3a203d3f6762", "eml"); // Email [Outlook Express 6] (eml)
FILE_TYPE_MAP.put("5374616E64617264204A", "mdb"); // MS Access (mdb)
FILE_TYPE_MAP.put("252150532D41646F6265", "ps");
FILE_TYPE_MAP.put("255044462d312e", "pdf"); // Adobe Acrobat (pdf)
FILE_TYPE_MAP.put("2e524d46000000120001", "rmvb"); // rmvb/rm相同
FILE_TYPE_MAP.put("464c5601050000000900", "flv"); // flv与f4v相同
FILE_TYPE_MAP.put("0000001C66747970", "mp4");
FILE_TYPE_MAP.put("00000020667479706", "mp4");
FILE_TYPE_MAP.put("00000018667479706D70", "mp4");
FILE_TYPE_MAP.put("49443303000000002176", "mp3");
FILE_TYPE_MAP.put("000001ba210001000180", "mpg"); //
FILE_TYPE_MAP.put("3026b2758e66cf11a6d9", "wmv"); // wmv与asf相同
FILE_TYPE_MAP.put("52494646e27807005741", "wav"); // Wave (wav)
FILE_TYPE_MAP.put("52494646d07d60074156", "avi");
FILE_TYPE_MAP.put("4d546864000000060001", "mid"); // MIDI (mid)
FILE_TYPE_MAP.put("526172211a0700cf9073", "rar"); // WinRAR
FILE_TYPE_MAP.put("235468697320636f6e66", "ini");
FILE_TYPE_MAP.put("504B03040a0000000000", "jar");
FILE_TYPE_MAP.put("504B0304140008000800", "jar");
// MS Excel 注意wordmsi excel的文件头一样
FILE_TYPE_MAP.put("d0cf11e0a1b11ae10", "xls");
FILE_TYPE_MAP.put("504B0304", "zip");
FILE_TYPE_MAP.put("4d5a9000030000000400", "exe"); // 可执行文件
FILE_TYPE_MAP.put("3c25402070616765206c", "jsp"); // jsp文件
FILE_TYPE_MAP.put("4d616e69666573742d56", "mf"); // MF文件
FILE_TYPE_MAP.put("7061636b616765207765", "java"); // java文件
FILE_TYPE_MAP.put("406563686f206f66660d", "bat"); // bat文件
FILE_TYPE_MAP.put("1f8b0800000000000000", "gz"); // gz文件
FILE_TYPE_MAP.put("cafebabe0000002e0041", "class"); // class文件
FILE_TYPE_MAP.put("49545346030000006000", "chm"); // chm文件
FILE_TYPE_MAP.put("04000000010000001300", "mxp"); // mxp文件
FILE_TYPE_MAP.put("6431303a637265617465", "torrent");
FILE_TYPE_MAP.put("6D6F6F76", "mov"); // Quicktime (mov)
FILE_TYPE_MAP.put("FF575043", "wpd"); // WordPerfect (wpd)
FILE_TYPE_MAP.put("CFAD12FEC5FD746F", "dbx"); // Outlook Express (dbx)
FILE_TYPE_MAP.put("2142444E", "pst"); // Outlook (pst)
FILE_TYPE_MAP.put("AC9EBD8F", "qdf"); // Quicken (qdf)
FILE_TYPE_MAP.put("E3828596", "pwl"); // Windows Password (pwl)
FILE_TYPE_MAP.put("2E7261FD", "ram"); // Real Audio (ram)
// https://stackoverflow.com/questions/45321665/magic-number-for-google-image-format
FILE_TYPE_MAP.put("52494646", "webp");
}
private static final Map<String, String> FILE_TYPE_MAP = new ConcurrentSkipListMap<>();
/**
* 增加文件类型映射<br>
@ -116,7 +32,7 @@ public class FileTypeUtil {
* @param extName 文件扩展名
* @return 之前已经存在的文件扩展名
*/
public static String putFileType(final String fileStreamHexHead, final String extName) {
public static String putFileType(String fileStreamHexHead, String extName) {
return FILE_TYPE_MAP.put(fileStreamHexHead, extName);
}
@ -126,7 +42,7 @@ public class FileTypeUtil {
* @param fileStreamHexHead 文件流头部Hex信息
* @return 移除的文件扩展名
*/
public static String removeFileType(final String fileStreamHexHead) {
public static String removeFileType(String fileStreamHexHead) {
return FILE_TYPE_MAP.remove(fileStreamHexHead);
}
@ -136,32 +52,57 @@ public class FileTypeUtil {
* @param fileStreamHexHead 文件流头部16进制字符串
* @return 文件类型未找到为{@code null}
*/
public static String getType(final String fileStreamHexHead) {
for (final Entry<String, String> fileTypeEntry : FILE_TYPE_MAP.entrySet()) {
public static String getType(String fileStreamHexHead) {
for (Entry<String, String> fileTypeEntry : FILE_TYPE_MAP.entrySet()) {
if (StrUtil.startWithIgnoreCase(fileStreamHexHead, fileTypeEntry.getKey())) {
return fileTypeEntry.getValue();
}
}
return null;
byte[] bytes = (HexUtil.decodeHex(fileStreamHexHead));
return FileMagicNumber.getMagicNumber(bytes).getExtension();
}
/**
* 根据文件流的头部信息获得文件类型
*
* @param in 文件流
* @param fileHeadSize 自定义读取文件头部的大小
* @return 文件类型未找到为{@code null}
*/
public static String getType(InputStream in,int fileHeadSize) throws IORuntimeException {
return getType((IoUtil.readHex(in, fileHeadSize,false)));
}
/**
* 根据文件流的头部信息获得文件类型<br>
* 注意此方法会读取头部28个bytes造成此流接下来读取时缺少部分bytes<br>
* 注意此方法会读取头部一些bytes造成此流接下来读取时缺少部分bytes<br>
* 因此如果想服用此流流需支持{@link InputStream#reset()}方法
*
* @param in {@link InputStream}
* @param isExact 是否精确匹配如果为false使用前64个bytes匹配如果为true使用前8192bytes匹配
* @return 类型文件的扩展名未找到为{@code null}
* @throws IORuntimeException 读取流引起的异常
* @throws IORuntimeException 读取流引起的异常
*/
public static String getType(final InputStream in) throws IORuntimeException {
return getType(readHex28Upper(in));
public static String getType(InputStream in,boolean isExact) throws IORuntimeException {
return isExact
?getType(readHex8192Upper(in))
:getType(readHex64Upper(in));
}
/**
* 根据文件流的头部信息获得文件类型<br>
* 注意此方法会读取头部64个bytes造成此流接下来读取时缺少部分bytes<br>
* 因此如果想服用此流流需支持{@link InputStream#reset()}方法
* @param in {@link InputStream}
* @return 类型文件的扩展名未找到为{@code null}
* @throws IORuntimeException 读取流引起的异常
*/
public static String getType(InputStream in) throws IORuntimeException {
return getType(in,false);
}
/**
* 根据文件流的头部信息获得文件类型
* 注意此方法会读取头部28个bytes造成此流接下来读取时缺少部分bytes<br>
* 注意此方法会读取头部64个bytes造成此流接下来读取时缺少部分bytes<br>
* 因此如果想服用此流流需支持{@link InputStream#reset()}方法
*
* <pre>
@ -173,24 +114,33 @@ public class FileTypeUtil {
* @param in {@link InputStream}
* @param filename 文件名
* @return 类型文件的扩展名未找到为{@code null}
* @throws IORuntimeException 读取流引起的异常
* @throws IORuntimeException 读取流引起的异常
*/
public static String getType(final InputStream in, final String filename) {
String typeName = getType(in);
public static String getType(InputStream in, String filename) throws IORuntimeException {
return getType(in,filename,false);
}
/**
* 根据文件流的头部信息获得文件类型
* 注意此方法会读取头部一些bytes造成此流接下来读取时缺少部分bytes<br>
* 因此如果想服用此流流需支持{@link InputStream#reset()}方法
*
* <pre>
* 1无法识别类型默认按照扩展名识别
* 2xlsdocmsi头信息无法区分按照扩展名区分
* 3zip可能为docxxlsxpptxjarwarofd头信息无法区分按照扩展名区分
* </pre>
* @param in {@link InputStream}
* @param filename 文件名
* @param isExact 是否精确匹配如果为false使用前64个bytes匹配如果为true使用前8192bytes匹配
* @return 类型文件的扩展名未找到为{@code null}
* @throws IORuntimeException 读取流引起的异常
*/
public static String getType(InputStream in, String filename,boolean isExact) throws IORuntimeException {
String typeName = getType(in,isExact);
if (null == typeName) {
// 未成功识别类型扩展名辅助识别
typeName = FileUtil.extName(filename);
} else if ("xls".equals(typeName)) {
// xlsdocmsi的头一样使用扩展名辅助判断
final String extName = FileUtil.extName(filename);
if ("doc".equalsIgnoreCase(extName)) {
typeName = "doc";
} else if ("msi".equalsIgnoreCase(extName)) {
typeName = "msi";
} else if ("ppt".equalsIgnoreCase(extName)) {
typeName = "ppt";
}
} else if ("zip".equals(typeName)) {
// zip可能为docxxlsxpptxjarwarofd等格式扩展名辅助判断
final String extName = FileUtil.extName(filename);
@ -235,21 +185,51 @@ public class FileTypeUtil {
* <pre>
* 1无法识别类型默认按照扩展名识别
* 2xlsdocmsi头信息无法区分按照扩展名区分
* 3zip可能为docxxlsxpptxjarwar头信息无法区分按照扩展名区分
* 3zip可能为jarwar头信息无法区分按照扩展名区分
* </pre>
*
* @param file 文件 {@link File}
* @param isExact 是否精确匹配如果为false使用前64个bytes匹配如果为true使用前8192bytes匹配
* @return 类型文件的扩展名未找到为{@code null}
* @throws IORuntimeException 读取文件引起的异常
*/
public static String getType(File file,boolean isExact) throws IORuntimeException {
FileInputStream in = null;
try {
in = IoUtil.toStream(file);
return getType(in, file.getName(),isExact);
} finally {
IoUtil.close(in);
}
}
/**
* 根据文件流的头部信息获得文件类型
*
* <pre>
* 1无法识别类型默认按照扩展名识别
* 2xlsdocmsi头信息无法区分按照扩展名区分
* 3zip可能为jarwar头信息无法区分按照扩展名区分
* </pre>
*
* @param file 文件 {@link File}
* @return 类型文件的扩展名未找到为{@code null}
* @throws IORuntimeException 读取文件引起的异常
* @throws IORuntimeException 读取文件引起的异常
*/
public static String getType(final File file) throws IORuntimeException {
FileInputStream in = null;
try {
in = IoUtil.toStream(file);
return getType(in, file.getName());
} finally {
IoUtil.close(in);
}
public static String getType(File file) throws IORuntimeException {
return getType(file,false);
}
/**
* 通过路径获得文件类型
*
* @param path 路径绝对路径或相对ClassPath的路径
* @param isExact 是否精确匹配如果为false使用前64个bytes匹配如果为true使用前8192bytes匹配
* @return 类型
* @throws IORuntimeException 读取文件引起的异常
*/
public static String getTypeByPath(String path,boolean isExact) throws IORuntimeException {
return getType(FileUtil.file(path),isExact);
}
/**
@ -257,31 +237,36 @@ public class FileTypeUtil {
*
* @param path 路径绝对路径或相对ClassPath的路径
* @return 类型
* @throws IORuntimeException 读取文件引起的异常
* @throws IORuntimeException 读取文件引起的异常
*/
public static String getTypeByPath(final String path) throws IORuntimeException {
return getType(FileUtil.file(path));
public static String getTypeByPath(String path) throws IORuntimeException {
return getTypeByPath(path,false);
}
/**
* 从流中读取前28个byte并转换为16进制字母部分使用大写
* 从流中读取前8192个byte并转换为16进制字母部分使用大写
*
* @param in {@link InputStream}
* @return 16进制字符串
* @throws IORuntimeException IO异常
*/
public static String readHex28Upper(final InputStream in) throws IORuntimeException {
return IoUtil.readHex(in, 28, false);
private static String readHex8192Upper(final InputStream in) throws IORuntimeException {
try {
final int i = in.available();
return IoUtil.readHex(in, Math.min(8192, in.available()), false);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
/**
* 从流中读取前28个byte并转换为16进制字母部分使用小写
* 从流中读取前64个byte并转换为16进制字母部分使用大
*
* @param in {@link InputStream}
* @return 16进制字符串
* @throws IORuntimeException IO异常
*/
public static String readHex28Lower(final InputStream in) throws IORuntimeException {
return IoUtil.readHex(in, 28, true);
private static String readHex64Upper(InputStream in) throws IORuntimeException {
return IoUtil.readHex(in, 64, false);
}
}

View File

@ -510,6 +510,12 @@ public class PathUtil {
public static Path moveContent(final Path src, final Path target, final boolean isOverride) {
Assert.notNull(src, "Src path must be not null !");
Assert.notNull(target, "Target path must be not null !");
if(equals(src, target)){
// issue#2845当用户传入目标路径与源路径一致时直接返回否则会导致删除风险
return target;
}
final CopyOption[] options = isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{};
// 自动创建目标的父目录

View File

@ -294,7 +294,7 @@ public class FieldUtil {
try {
field.set(obj instanceof Class ? null : obj, value);
} catch (final IllegalAccessException e) {
throw new UtilException(e, "IllegalAccess for {}.{}", obj, field.getName());
throw new UtilException(e, "IllegalAccess for [{}.{}]", null == obj ? field.getDeclaringClass() : obj, field.getName());
}
}

View File

@ -249,6 +249,7 @@ public class ModifierUtil {
if (null == field || false == hasModifier(field, ModifierUtil.ModifierType.FINAL)) {
return;
}
//将字段的访问权限设为true即去除private修饰符的影响
if (false == field.isAccessible()) {
field.setAccessible(true);
@ -263,7 +264,7 @@ public class ModifierUtil {
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
} catch (final NoSuchFieldException | IllegalAccessException e) {
//内部工具类基本不抛出异常
throw new UtilException(e, "IllegalAccess for {}.{}", field.getDeclaringClass(), field.getName());
throw new UtilException(e, "IllegalAccess for [{}.{}]", field.getDeclaringClass(), field.getName());
}
}
//-------------------------------------------------------------------------------------------------------- Private method start

View File

@ -133,6 +133,34 @@ public class CoordinateUtil {
return gcj02ToWgs84(gcj02.lng, gcj02.lat);
}
/**
* WGS84 坐标转为 墨卡托投影
*
* @param lng 经度值
* @param lat 纬度值
* @return 墨卡托投影
*/
public static Coordinate wgs84ToMercator(final double lng, final double lat) {
final double x = lng * 20037508.342789244 / 180;
double y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
y = y * 20037508.342789244 / 180;
return new Coordinate(x, y);
}
/**
* 墨卡托投影 转为 WGS84 坐标
*
* @param mercatorX 墨卡托X坐标
* @param mercatorY 墨卡托Y坐标
* @return WGS84 坐标
*/
public static Coordinate mercatorToWgs84(final double mercatorX, final double mercatorY) {
final double x = mercatorX / 20037508.342789244 * 180;
double y = mercatorY / 20037508.342789244 * 180;
y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
return new Coordinate(x, y);
}
//----------------------------------------------------------------------------------- Private methods begin
/**

View File

@ -41,7 +41,6 @@ import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
@ -333,51 +332,6 @@ public class XmlUtil {
xmlStr = cleanInvalid(xmlStr);
return readXML(StrUtil.getReader(xmlStr));
}
/**
* 从XML中读取对象 Reads serialized object from the XML file.
*
* @param <T> 对象类型
* @param source XML文件
* @return 对象
*/
public static <T> T readObjectFromXml(final File source) {
return readObjectFromXml(new InputSource(FileUtil.getInputStream(source)));
}
/**
* 从XML中读取对象 Reads serialized object from the XML file.
*
* @param <T> 对象类型
* @param xmlStr XML内容
* @return 对象
* @since 3.2.0
*/
public static <T> T readObjectFromXml(final String xmlStr) {
return readObjectFromXml(new InputSource(StrUtil.getReader(xmlStr)));
}
/**
* 从XML中读取对象 Reads serialized object from the XML file.
*
* @param <T> 对象类型
* @param source {@link InputSource}
* @return 对象
* @since 3.2.0
*/
@SuppressWarnings("unchecked")
public static <T> T readObjectFromXml(final InputSource source) {
Object result;
XMLDecoder xmldec = null;
try {
xmldec = new XMLDecoder(source);
result = xmldec.readObject();
} finally {
IoUtil.close(xmldec);
}
return (T) result;
}
// -------------------------------------------------------------------------------------- Write
/**

View File

@ -56,18 +56,6 @@ public class FileTypeUtilTest {
Console.log(type);
}
@Test
@Ignore
public void ofdTest() {
final File file = FileUtil.file("e:/test.ofd");
final String hex = FileTypeUtil.readHex28Upper(FileUtil.getInputStream(file));
Console.log(hex);
final String type = FileTypeUtil.getType(file);
Console.log(type);
Assert.assertEquals("ofd", type);
}
@Test
@Ignore
public void inputStreamAndFilenameTest() {
@ -97,16 +85,4 @@ public class FileTypeUtilTest {
final String type = FileTypeUtil.getType(inputStream);
Console.log(type);
}
@Test
public void readHex28LowerTest() {
final String s = FileTypeUtil.readHex28Lower(ResourceUtil.getStream("hutool.jpg"));
Assert.assertEquals("ffd8ffe000104a46494600010101006000600000ffe1095845786966", s);
}
@Test
public void readHex28UpperTest() {
final String s = FileTypeUtil.readHex28Upper(ResourceUtil.getStream("hutool.jpg"));
Assert.assertEquals("FFD8FFE000104A46494600010101006000600000FFE1095845786966", s);
}
}

View File

@ -50,6 +50,10 @@ public class HexUtilTest {
// 错误的
a = "0x0000001000T00001158e460913d00000";
Assert.assertFalse(HexUtil.isHexNumber(a));
// 错误的,https://github.com/dromara/hutool/issues/2857
a = "-1";
Assert.assertFalse(HexUtil.isHexNumber(a));
}
@Test

View File

@ -1,6 +1,7 @@
package cn.hutool.crypto.symmetric;
import cn.hutool.core.text.StrUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
@ -12,6 +13,59 @@ import org.junit.Test;
*/
public class DesTest {
@Test
public void desTest() {
final String content = "test中文";
final byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.DES.getValue()).getEncoded();
final SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DES, key);
final byte[] encrypt = des.encrypt(content);
final byte[] decrypt = des.decrypt(encrypt);
Assert.assertEquals(content, StrUtil.utf8Str(decrypt));
final String encryptHex = des.encryptHex(content);
final String decryptStr = des.decryptStr(encryptHex);
Assert.assertEquals(content, decryptStr);
}
@Test
public void desTest2() {
final String content = "test中文";
final byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.DES.getValue()).getEncoded();
final DES des = SecureUtil.des(key);
final byte[] encrypt = des.encrypt(content);
final byte[] decrypt = des.decrypt(encrypt);
Assert.assertEquals(content, StrUtil.utf8Str(decrypt));
final String encryptHex = des.encryptHex(content);
final String decryptStr = des.decryptStr(encryptHex);
Assert.assertEquals(content, decryptStr);
}
@Test
public void desTest3() {
final String content = "test中文";
final DES des = new DES(Mode.CTS, Padding.PKCS5Padding, "0CoJUm6Qyw8W8jud".getBytes(), "01020304".getBytes());
final byte[] encrypt = des.encrypt(content);
final byte[] decrypt = des.decrypt(encrypt);
Assert.assertEquals(content, StrUtil.utf8Str(decrypt));
final String encryptHex = des.encryptHex(content);
final String decryptStr = des.decryptStr(encryptHex);
Assert.assertEquals(content, decryptStr);
}
@Test
public void encryptDecryptTest(){
final String content = "我是一个测试的test字符串123";

View File

@ -172,59 +172,6 @@ public class SymmetricTest {
Assert.assertEquals(content, decryptStr);
}
@Test
public void desTest() {
final String content = "test中文";
final byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.DES.getValue()).getEncoded();
final SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DES, key);
final byte[] encrypt = des.encrypt(content);
final byte[] decrypt = des.decrypt(encrypt);
Assert.assertEquals(content, StrUtil.utf8Str(decrypt));
final String encryptHex = des.encryptHex(content);
final String decryptStr = des.decryptStr(encryptHex);
Assert.assertEquals(content, decryptStr);
}
@Test
public void desTest2() {
final String content = "test中文";
final byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.DES.getValue()).getEncoded();
final DES des = SecureUtil.des(key);
final byte[] encrypt = des.encrypt(content);
final byte[] decrypt = des.decrypt(encrypt);
Assert.assertEquals(content, StrUtil.utf8Str(decrypt));
final String encryptHex = des.encryptHex(content);
final String decryptStr = des.decryptStr(encryptHex);
Assert.assertEquals(content, decryptStr);
}
@Test
public void desTest3() {
final String content = "test中文";
final DES des = new DES(Mode.CTS, Padding.PKCS5Padding, "0CoJUm6Qyw8W8jud".getBytes(), "01020304".getBytes());
final byte[] encrypt = des.encrypt(content);
final byte[] decrypt = des.decrypt(encrypt);
Assert.assertEquals(content, StrUtil.utf8Str(decrypt));
final String encryptHex = des.encryptHex(content);
final String decryptStr = des.decryptStr(encryptHex);
Assert.assertEquals(content, decryptStr);
}
@Test
public void desdeTest() {
final String content = "test中文";

View File

@ -0,0 +1,11 @@
package cn.hutool.http.client;
import cn.hutool.http.client.engine.jdk.HttpUrlConnectionUtil;
import org.junit.Test;
public class HttpUrlConnectionUtilTest {
@Test
public void allowPatchTest() {
HttpUrlConnectionUtil.allowPatch();
}
}