通过添加系统属性hutool.crypto.decodeHex强制关闭hex识别以解决hex和Base64歧义问题

This commit is contained in:
Looly
2024-02-10 08:37:15 +08:00
parent 6accf8fca0
commit e948273f2d
26 changed files with 169 additions and 158 deletions

View File

@@ -13,6 +13,7 @@
package org.dromara.hutool.core.codec;
import org.dromara.hutool.core.codec.binary.Base16Codec;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.CharPool;
import org.dromara.hutool.core.text.StrUtil;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Copyright (c) 2023-2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
@@ -10,13 +10,12 @@
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.codec;
package org.dromara.hutool.core.codec.binary;
import org.dromara.hutool.core.codec.binary.Base16Codec;
import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ByteUtil;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.util.CharsetUtil;
import java.awt.Color;
@@ -35,43 +34,15 @@ import java.nio.charset.Charset;
*/
public class HexUtil {
/**
* 判断给定字符串是否为16进制数<br>
* 如果是需要使用对应数字类型对象的{@code decode}方法解码<br>
* 例如{@code Integer.decode}方法解码int类型的16进制数字
*
* @param value
* @return 是否为16进制
*/
public static boolean isHexNumber(final String value) {
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)) {
index++;
}
try {
new BigInteger(value.substring(index), 16);
} catch (final NumberFormatException e) {
return false;
}
return true;
}
// ---------------------------------------------------------------------------------------------------- encode
// region ----- encode
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @return 十六进制char[]
*/
public static char[] encodeHex(final byte[] data) {
return encodeHex(data, true);
public static char[] encode(final byte[] data) {
return encode(data, true);
}
/**
@@ -81,8 +52,8 @@ public class HexUtil {
* @param charset 编码
* @return 十六进制char[]
*/
public static char[] encodeHex(final String str, final Charset charset) {
return encodeHex(ByteUtil.toBytes(str, charset), true);
public static char[] encode(final String str, final Charset charset) {
return encode(ByteUtil.toBytes(str, charset), true);
}
/**
@@ -92,7 +63,7 @@ public class HexUtil {
* @param toLowerCase {@code true} 传换成小写格式 {@code false} 传换成大写格式
* @return 十六进制char[]如果提供的data为{@code null}返回{@code null}
*/
public static char[] encodeHex(final byte[] data, final boolean toLowerCase) {
public static char[] encode(final byte[] data, final boolean toLowerCase) {
if(null == data){
return null;
}
@@ -105,8 +76,18 @@ public class HexUtil {
* @param data byte[]
* @return 十六进制String
*/
public static String encodeHexStr(final byte[] data) {
return encodeHexStr(data, true);
public static String encodeStr(final byte[] data) {
return encodeStr(data, true);
}
/**
* 将字符串转换为十六进制字符串结果为小写默认编码是UTF-8
*
* @param data 被编码的字符串
* @return 十六进制String
*/
public static String encodeStr(final String data) {
return encodeStr(data, CharsetUtil.UTF_8);
}
/**
@@ -116,18 +97,8 @@ public class HexUtil {
* @param charset 编码
* @return 十六进制String
*/
public static String encodeHexStr(final String data, final Charset charset) {
return encodeHexStr(ByteUtil.toBytes(data, charset), true);
}
/**
* 将字符串转换为十六进制字符串结果为小写默认编码是UTF-8
*
* @param data 被编码的字符串
* @return 十六进制String
*/
public static String encodeHexStr(final String data) {
return encodeHexStr(data, CharsetUtil.UTF_8);
public static String encodeStr(final String data, final Charset charset) {
return encodeStr(ByteUtil.toBytes(data, charset), true);
}
/**
@@ -137,11 +108,12 @@ public class HexUtil {
* @param toLowerCase {@code true} 传换成小写格式 {@code false} 传换成大写格式
* @return 十六进制String
*/
public static String encodeHexStr(final byte[] data, final boolean toLowerCase) {
return StrUtil.str(encodeHex(data, toLowerCase), CharsetUtil.UTF_8);
public static String encodeStr(final byte[] data, final boolean toLowerCase) {
return StrUtil.str(encode(data, toLowerCase), CharsetUtil.UTF_8);
}
// endregion
// ---------------------------------------------------------------------------------------------------- decode
// region ----- decode
/**
* 将十六进制字符数组转换为字符串默认编码UTF-8
@@ -149,8 +121,8 @@ public class HexUtil {
* @param hexStr 十六进制String
* @return 字符串
*/
public static String decodeHexStr(final String hexStr) {
return decodeHexStr(hexStr, CharsetUtil.UTF_8);
public static String decodeStr(final String hexStr) {
return decodeStr(hexStr, CharsetUtil.UTF_8);
}
/**
@@ -160,11 +132,11 @@ public class HexUtil {
* @param charset 编码
* @return 字符串
*/
public static String decodeHexStr(final String hexStr, final Charset charset) {
public static String decodeStr(final String hexStr, final Charset charset) {
if (StrUtil.isEmpty(hexStr)) {
return hexStr;
}
return StrUtil.str(decodeHex(hexStr), charset);
return StrUtil.str(decode(hexStr), charset);
}
/**
@@ -174,8 +146,8 @@ public class HexUtil {
* @param charset 编码
* @return 字符串
*/
public static String decodeHexStr(final char[] hexData, final Charset charset) {
return StrUtil.str(decodeHex(hexData), charset);
public static String decodeStr(final char[] hexData, final Charset charset) {
return StrUtil.str(decode(hexData), charset);
}
/**
@@ -184,8 +156,8 @@ public class HexUtil {
* @param hexStr 十六进制String
* @return byte[]
*/
public static byte[] decodeHex(final String hexStr) {
return decodeHex((CharSequence) hexStr);
public static byte[] decode(final String hexStr) {
return decode((CharSequence) hexStr);
}
/**
@@ -195,8 +167,8 @@ public class HexUtil {
* @return byte[]
* @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度将抛出运行时异常
*/
public static byte[] decodeHex(final char[] hexData) {
return decodeHex(String.valueOf(hexData));
public static byte[] decode(final char[] hexData) {
return decode(String.valueOf(hexData));
}
/**
@@ -207,11 +179,13 @@ public class HexUtil {
* @throws HutoolException 如果源十六进制字符数组是一个奇怪的长度将抛出运行时异常
* @since 5.6.6
*/
public static byte[] decodeHex(final CharSequence hexData) {
public static byte[] decode(final CharSequence hexData) {
return Base16Codec.CODEC_LOWER.decode(hexData);
}
// ---------------------------------------------------------------------------------------- Color
// endregion
// region ----- Color
/**
* {@link Color}编码为Hex形式
@@ -264,6 +238,35 @@ public class HexUtil {
return Color.decode(hexColor);
}
// endregion
/**
* 判断给定字符串是否为16进制数<br>
* 如果是需要使用对应数字类型对象的{@code decode}方法解码<br>
* 例如{@code Integer.decode}方法解码int类型的16进制数字
*
* @param value
* @return 是否为16进制
*/
public static boolean isHexNumber(final String value) {
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)) {
index++;
}
try {
new BigInteger(value.substring(index), 16);
} catch (final NumberFormatException e) {
return false;
}
return true;
}
/**
* 将指定int值转换为Unicode字符串形式常用于特殊字符例如汉字转Unicode形式<br>
* 转换的字符串如果u后不足4位则前面用0填充例如

View File

@@ -14,7 +14,7 @@ package org.dromara.hutool.core.convert;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.classloader.ClassLoaderUtil;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.convert.impl.CollectionConverter;
import org.dromara.hutool.core.convert.impl.EnumConverter;
import org.dromara.hutool.core.convert.impl.MapConverter;
@@ -874,10 +874,10 @@ public class Convert {
* @param str 待转换的ASCII字符串
* @param charset 编码
* @return 16进制字符串
* @see HexUtil#encodeHexStr(String, Charset)
* @see HexUtil#encodeStr(String, Charset)
*/
public static String toHex(final String str, final Charset charset) {
return HexUtil.encodeHexStr(str, charset);
return HexUtil.encodeStr(str, charset);
}
/**
@@ -885,10 +885,10 @@ public class Convert {
*
* @param bytes 被转换的byte数组
* @return 转换后的值
* @see HexUtil#encodeHexStr(byte[])
* @see HexUtil#encodeStr(byte[])
*/
public static String toHex(final byte[] bytes) {
return HexUtil.encodeHexStr(bytes);
return HexUtil.encodeStr(bytes);
}
/**
@@ -896,10 +896,10 @@ public class Convert {
*
* @param src Byte字符串每个Byte之间没有分隔符
* @return byte[]
* @see HexUtil#decodeHex(char[])
* @see HexUtil#decode(char[])
*/
public static byte[] hexToBytes(final String src) {
return HexUtil.decodeHex(src.toCharArray());
return HexUtil.decode(src.toCharArray());
}
/**
@@ -908,11 +908,11 @@ public class Convert {
* @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
* @param charset 编码 {@link Charset}
* @return 对应的字符串
* @see HexUtil#decodeHexStr(String, Charset)
* @see HexUtil#decodeStr(String, Charset)
* @since 4.1.11
*/
public static String hexToStr(final String hexStr, final Charset charset) {
return HexUtil.decodeHexStr(hexStr, charset);
return HexUtil.decodeStr(hexStr, charset);
}
/**

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.io;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.collection.iter.LineIter;
import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.io.copy.FileChannelCopier;
@@ -404,7 +404,7 @@ public class IoUtil extends NioUtil {
* @throws IORuntimeException IO异常
*/
public static String readHex(final InputStream in, final int length, final boolean toLowerCase) throws IORuntimeException {
return HexUtil.encodeHexStr(readBytes(in, length), toLowerCase);
return HexUtil.encodeStr(readBytes(in, length), toLowerCase);
}
/**

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.io.checksum.crc16;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.io.Serializable;

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.io.file;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.text.StrUtil;
@@ -71,7 +71,7 @@ public class FileTypeUtil {
return fileTypeEntry.getValue();
}
}
final byte[] bytes = (HexUtil.decodeHex(fileStreamHexHead));
final byte[] bytes = (HexUtil.decode(fileStreamHexHead));
return FileMagicNumber.getMagicNumber(bytes).getExtension();
}

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.text;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
/**
* 提供Unicode字符串和普通字符串之间的转换

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.codec.hash.metro;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.codec.Number128;
import org.dromara.hutool.core.util.ByteUtil;
import org.junit.jupiter.api.Assertions;
@@ -128,6 +128,6 @@ public class MetroHash128Test {
}
private static String hex(final byte[] bytes){
return HexUtil.encodeHexStr(bytes).toUpperCase();
return HexUtil.encodeStr(bytes).toUpperCase();
}
}

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.codec.hash.metro;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.util.ByteUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -125,6 +125,6 @@ public class MetroHash64Test {
}
private static String hex(final byte[] bytes){
return HexUtil.encodeHexStr(bytes).toUpperCase();
return HexUtil.encodeStr(bytes).toUpperCase();
}
}

View File

@@ -13,7 +13,7 @@
package org.dromara.hutool.core.codec.hash.metro;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.codec.hash.CityHash;
import org.dromara.hutool.core.util.ByteUtil;
import org.dromara.hutool.core.util.CharsetUtil;

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.convert;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.collection.set.SetUtil;
import org.dromara.hutool.core.date.DateException;
import org.dromara.hutool.core.date.DateUtil;
@@ -416,7 +416,7 @@ public class ConvertTest {
public void toFloatTest(){
// https://gitee.com/dromara/hutool/issues/I4M0E4
final String hex2 = "CD0CCB43";
final byte[] value = HexUtil.decodeHex(hex2);
final byte[] value = HexUtil.decode(hex2);
final float f = Convert.toFloat(value);
Assertions.assertEquals(406.1F, f, 0);
}

View File

@@ -12,7 +12,7 @@
package org.dromara.hutool.core.io.checksum;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.io.checksum.crc16.CRC16XModem;
import org.dromara.hutool.core.util.ByteUtil;
import org.junit.jupiter.api.Assertions;

View File

@@ -12,8 +12,7 @@
package org.dromara.hutool.core.util;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -30,15 +29,15 @@ public class HexUtilTest {
public void hexStrTest(){
final String str = "我是一个字符串";
final String hex = HexUtil.encodeHexStr(str, CharsetUtil.UTF_8);
final String decodedStr = HexUtil.decodeHexStr(hex);
final String hex = HexUtil.encodeStr(str, CharsetUtil.UTF_8);
final String decodedStr = HexUtil.decodeStr(hex);
Assertions.assertEquals(str, decodedStr);
}
@Test
public void issueI50MI6Test(){
final String s = HexUtil.encodeHexStr("".getBytes(StandardCharsets.UTF_16BE));
final String s = HexUtil.encodeStr("".getBytes(StandardCharsets.UTF_16BE));
Assertions.assertEquals("70df", s);
}
@@ -75,8 +74,8 @@ public class HexUtilTest {
@Test
public void decodeTest(){
final String str = "e8c670380cb220095268f40221fc748fa6ac39d6e930e63c30da68bad97f885d";
Assertions.assertArrayEquals(HexUtil.decodeHex(str),
HexUtil.decodeHex(str.toUpperCase()));
Assertions.assertArrayEquals(HexUtil.decode(str),
HexUtil.decode(str.toUpperCase()));
}
@Test
@@ -88,8 +87,8 @@ public class HexUtilTest {
@Test
public void decodeHexTest(){
final String s = HexUtil.encodeHexStr("6");
final String s1 = HexUtil.decodeHexStr(s);
final String s = HexUtil.encodeStr("6");
final String s1 = HexUtil.decodeStr(s);
Assertions.assertEquals("6", s1);
}
}