mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
Refactor (hutool-core): 修改数字转换的实现,增加按照指定端序转换
# 修改 1. 因为跨平台通信时由于平台原因存在字节序不一致的情况,所以在对数据进行转换的时候需要指定端序,按照两边的约定选择是使用大端序还是小端序,因此重构原有 int、short 和 long 与 byte[] 之间互相转换的实现,增加可以指定转换方式,补充大端序转换实现,同时保留原有方法,默认设置为小端序转换。 2. 将部分魔法值使用常量进行替代 3. 对于实现的修改,补充了测试方法的实现,完成不同端序的转换测试
This commit is contained in:
parent
65adb148c1
commit
7c01feece9
@ -14,16 +14,11 @@ import cn.hutool.core.util.StrUtil;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -1044,92 +1039,223 @@ public class Convert {
|
||||
}
|
||||
|
||||
/**
|
||||
* byte数组转short
|
||||
* byte数组转short<br>
|
||||
* 默认以小端序转换
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @return short值
|
||||
* @since 3.2.0
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static short bytesToShort(byte[] bytes) {
|
||||
return (short) (bytes[1] & 0xff | (bytes[0] & 0xff) << 8);
|
||||
return bytesToShort(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* short转byte数组
|
||||
* byte数组转short<br>
|
||||
* 自定义端序
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @param byteOrder 端序
|
||||
* @return short值
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static short bytesToShort(byte[] bytes, ByteOrder byteOrder) {
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
return (short) (bytes[1] & 0xff | (bytes[0] & 0xff) << Byte.SIZE);
|
||||
} else {
|
||||
return (short) (bytes[0] & 0xff | (bytes[1] & 0xff) << Byte.SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* short转byte数组<br>
|
||||
* 默认以小端序转换
|
||||
*
|
||||
* @param shortValue short值
|
||||
* @return byte数组
|
||||
* @since 3.2.0
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static byte[] shortToBytes(short shortValue) {
|
||||
byte[] b = new byte[2];
|
||||
b[1] = (byte) (shortValue & 0xff);
|
||||
b[0] = (byte) ((shortValue >> 8) & 0xff);
|
||||
return shortToBytes(shortValue, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* short转byte数组<br>
|
||||
* 自定义端序
|
||||
*
|
||||
* @param shortValue short值
|
||||
* @param byteOrder 端序
|
||||
* @return byte数组
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static byte[] shortToBytes(short shortValue, ByteOrder byteOrder) {
|
||||
byte[] b = new byte[Short.BYTES];
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
b[1] = (byte) (shortValue & 0xff);
|
||||
b[0] = (byte) ((shortValue >> Byte.SIZE) & 0xff);
|
||||
} else {
|
||||
b[0] = (byte) (shortValue & 0xff);
|
||||
b[1] = (byte) ((shortValue >> Byte.SIZE) & 0xff);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte[]转int值
|
||||
* byte[]转int值<br>
|
||||
* 默认以小端序转换
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @return int值
|
||||
* @since 3.2.0
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static int bytesToInt(byte[] bytes) {
|
||||
return bytes[3] & 0xFF | //
|
||||
(bytes[2] & 0xFF) << 8 | //
|
||||
(bytes[1] & 0xFF) << 16 | //
|
||||
(bytes[0] & 0xFF) << 24; //
|
||||
return bytesToInt(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* int转byte数组
|
||||
* byte[]转int值<br>
|
||||
* 自定义端序
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @param byteOrder 端序
|
||||
* @return int值
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static int bytesToInt(byte[] bytes, ByteOrder byteOrder) {
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
return bytes[3] & 0xFF | //
|
||||
(bytes[2] & 0xFF) << 8 | //
|
||||
(bytes[1] & 0xFF) << 16 | //
|
||||
(bytes[0] & 0xFF) << 24; //
|
||||
} else {
|
||||
return bytes[0] & 0xFF | //
|
||||
(bytes[1] & 0xFF) << 8 | //
|
||||
(bytes[2] & 0xFF) << 16 | //
|
||||
(bytes[3] & 0xFF) << 24; //
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* int转byte数组<br>
|
||||
* 默认以小端序转换
|
||||
*
|
||||
* @param intValue int值
|
||||
* @return byte数组
|
||||
* @since 3.2.0
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static byte[] intToBytes(int intValue) {
|
||||
return new byte[] { //
|
||||
(byte) ((intValue >> 24) & 0xFF), //
|
||||
(byte) ((intValue >> 16) & 0xFF), //
|
||||
(byte) ((intValue >> 8) & 0xFF), //
|
||||
(byte) (intValue & 0xFF) //
|
||||
};
|
||||
return intToBytes(intValue, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* int转byte数组<br>
|
||||
* 自定义端序
|
||||
*
|
||||
* @param intValue int值
|
||||
* @param byteOrder 端序
|
||||
* @return byte数组
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static byte[] intToBytes(int intValue, ByteOrder byteOrder) {
|
||||
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
return new byte[]{ //
|
||||
(byte) ((intValue >> 24) & 0xFF), //
|
||||
(byte) ((intValue >> 16) & 0xFF), //
|
||||
(byte) ((intValue >> 8) & 0xFF), //
|
||||
(byte) (intValue & 0xFF) //
|
||||
};
|
||||
|
||||
} else {
|
||||
return new byte[]{ //
|
||||
(byte) (intValue & 0xFF), //
|
||||
(byte) ((intValue >> 8) & 0xFF), //
|
||||
(byte) ((intValue >> 16) & 0xFF), //
|
||||
(byte) ((intValue >> 24) & 0xFF) //
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* long转byte数组<br>
|
||||
* 默认以小端序转换<br>
|
||||
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||
*
|
||||
* @param longValue long值
|
||||
* @return byte数组
|
||||
* @since 3.2.0
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static byte[] longToBytes(long longValue) {
|
||||
// Magic number 8 should be defined as Long.SIZE / Byte.SIZE
|
||||
final byte[] result = new byte[8];
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
result[i] = (byte) (longValue & 0xFF);
|
||||
longValue >>= 8;
|
||||
return longToBytes(longValue, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* long转byte数组<br>
|
||||
* 自定义端序<br>
|
||||
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||
*
|
||||
* @param longValue long值
|
||||
* @param byteOrder 端序
|
||||
* @return byte数组
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static byte[] longToBytes(long longValue, ByteOrder byteOrder) {
|
||||
byte[] result = new byte[Long.BYTES];
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
for (int i = (result.length - 1); i >= 0; i--) {
|
||||
result[i] = (byte) (longValue & 0xFF);
|
||||
longValue >>= Byte.SIZE;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = (byte) (longValue & 0xFF);
|
||||
longValue >>= Byte.SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte数组转long<br>
|
||||
* 默认以小端序转换<br>
|
||||
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @return long值
|
||||
* @since 3.2.0
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static long bytesToLong(byte[] bytes) {
|
||||
// Magic number 8 should be defined as Long.SIZE / Byte.SIZE
|
||||
return bytesToLong(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* byte数组转long<br>
|
||||
* 自定义端序<br>
|
||||
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @param byteOrder 端序
|
||||
* @return long值
|
||||
* @since 5.6.3
|
||||
*/
|
||||
public static long bytesToLong(byte[] bytes, ByteOrder byteOrder) {
|
||||
long values = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
values <<= 8;
|
||||
values |= (bytes[i] & 0xff);
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
for (int i = 0; i < Long.BYTES; i++) {
|
||||
values <<= Byte.SIZE;
|
||||
values |= (bytes[i] & 0xff);
|
||||
}
|
||||
} else {
|
||||
for (int i = (Long.BYTES - 1); i >= 0; i--) {
|
||||
values <<= Byte.SIZE;
|
||||
values |= (bytes[i] & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
@ -173,6 +174,35 @@ public class ConvertTest {
|
||||
Assert.assertEquals(int2, int3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intAndBytesLittleEndianTest() {
|
||||
// 测试 int 转小端序 byte 数组
|
||||
int int1 = 1417;
|
||||
|
||||
byte[] bytesInt = Convert.intToBytes(int1, ByteOrder.LITTLE_ENDIAN);
|
||||
int int2 = Convert.bytesToInt(bytesInt, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(int1, int2);
|
||||
|
||||
byte[] bytesInt2 = Convert.intToBytes(int1, ByteOrder.LITTLE_ENDIAN);
|
||||
int int3 = Convert.bytesToInt(bytesInt2, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(int1, int3);
|
||||
|
||||
byte[] bytesInt3 = Convert.intToBytes(int1, ByteOrder.LITTLE_ENDIAN);
|
||||
int int4 = Convert.bytesToInt(bytesInt3, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(int1, int4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intAndBytesBigEndianTest() {
|
||||
// 测试 int 转大端序 byte 数组
|
||||
int int2 = 1417;
|
||||
byte[] bytesInt = Convert.intToBytes(int2, ByteOrder.BIG_ENDIAN);
|
||||
|
||||
// 测试大端序 byte 数组转 int
|
||||
int int3 = Convert.bytesToInt(bytesInt, ByteOrder.BIG_ENDIAN);
|
||||
Assert.assertEquals(int2, int3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndBytesTest() {
|
||||
// 测试 long 转 byte 数组
|
||||
@ -184,6 +214,35 @@ public class ConvertTest {
|
||||
Assert.assertEquals(long1, long2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndBytesLittleEndianTest() {
|
||||
// 测试 long 转 byte 数组
|
||||
long long1 = 2223;
|
||||
|
||||
byte[] bytesLong = Convert.longToBytes(long1, ByteOrder.LITTLE_ENDIAN);
|
||||
long long2 = Convert.bytesToLong(bytesLong, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(long1, long2);
|
||||
|
||||
byte[] bytesLong2 = Convert.longToBytes(long1);
|
||||
long long3 = Convert.bytesToLong(bytesLong2, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(long1, long3);
|
||||
|
||||
byte[] bytesLong3 = Convert.longToBytes(long1, ByteOrder.LITTLE_ENDIAN);
|
||||
long long4 = Convert.bytesToLong(bytesLong3);
|
||||
Assert.assertEquals(long1, long4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndBytesBigEndianTest() {
|
||||
// 测试大端序 long 转 byte 数组
|
||||
long long1 = 2223;
|
||||
|
||||
byte[] bytesLong = Convert.longToBytes(long1, ByteOrder.BIG_ENDIAN);
|
||||
long long2 = Convert.bytesToLong(bytesLong, ByteOrder.BIG_ENDIAN);
|
||||
|
||||
Assert.assertEquals(long1, long2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortAndBytesTest() {
|
||||
short short1 = 122;
|
||||
@ -194,8 +253,34 @@ public class ConvertTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toListTest(){
|
||||
List<String> list = Arrays.asList("1","2");
|
||||
public void shortAndBytesLittleEndianTest() {
|
||||
short short1 = 122;
|
||||
|
||||
byte[] bytes = Convert.shortToBytes(short1, ByteOrder.LITTLE_ENDIAN);
|
||||
short short2 = Convert.bytesToShort(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(short2, short1);
|
||||
|
||||
byte[] bytes2 = Convert.shortToBytes(short1);
|
||||
short short3 = Convert.bytesToShort(bytes2, ByteOrder.LITTLE_ENDIAN);
|
||||
Assert.assertEquals(short3, short1);
|
||||
|
||||
byte[] bytes3 = Convert.shortToBytes(short1, ByteOrder.LITTLE_ENDIAN);
|
||||
short short4 = Convert.bytesToShort(bytes3);
|
||||
Assert.assertEquals(short4, short1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortAndBytesBigEndianTest() {
|
||||
short short1 = 122;
|
||||
byte[] bytes = Convert.shortToBytes(short1, ByteOrder.BIG_ENDIAN);
|
||||
short short2 = Convert.bytesToShort(bytes, ByteOrder.BIG_ENDIAN);
|
||||
|
||||
Assert.assertEquals(short2, short1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toListTest() {
|
||||
List<String> list = Arrays.asList("1", "2");
|
||||
String str = Convert.toStr(list);
|
||||
List<String> list2 = Convert.toList(String.class, str);
|
||||
Assert.assertEquals("1", list2.get(0));
|
||||
|
Loading…
x
Reference in New Issue
Block a user