mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
d5e8c53b2b
commit
9261511574
@ -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)) {
|
||||
|
1238
hutool-core/src/main/java/cn/hutool/core/io/FileMagicNumber.java
Executable file
1238
hutool-core/src/main/java/cn/hutool/core/io/FileMagicNumber.java
Executable file
File diff suppressed because it is too large
Load Diff
@ -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>需要注意的是,xlsx、docx等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 注意:word、msi 和 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、无法识别类型默认按照扩展名识别
|
||||
* 2、xls、doc、msi头信息无法区分,按照扩展名区分
|
||||
* 3、zip可能为docx、xlsx、pptx、jar、war、ofd头信息无法区分,按照扩展名区分
|
||||
* </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)) {
|
||||
// xls、doc、msi的头一样,使用扩展名辅助判断
|
||||
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可能为docx、xlsx、pptx、jar、war、ofd等格式,扩展名辅助判断
|
||||
final String extName = FileUtil.extName(filename);
|
||||
@ -235,21 +185,51 @@ public class FileTypeUtil {
|
||||
* <pre>
|
||||
* 1、无法识别类型默认按照扩展名识别
|
||||
* 2、xls、doc、msi头信息无法区分,按照扩展名区分
|
||||
* 3、zip可能为docx、xlsx、pptx、jar、war头信息无法区分,按照扩展名区分
|
||||
* 3、zip可能为jar、war头信息无法区分,按照扩展名区分
|
||||
* </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、无法识别类型默认按照扩展名识别
|
||||
* 2、xls、doc、msi头信息无法区分,按照扩展名区分
|
||||
* 3、zip可能为jar、war头信息无法区分,按照扩展名区分
|
||||
* </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);
|
||||
}
|
||||
}
|
||||
|
@ -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[]{};
|
||||
|
||||
// 自动创建目标的父目录
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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中文";
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user