百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

夯实基础:Byte和各数据类型之间的转换

bigegpt 2024-08-23 11:42 2 浏览

在Java的网络编程中传输的经常是byte数组,但我们实际中使用的数据类型可能是任一种数据类型,这就需要在它们之间相互转换,转换的核心在于将其他类型的数据的每一位转换成byte类型的数据。


下面给出相关的转换代码——

1.short与byte数组的互转

/**
* 转换short为byte
*
* @param b
* @param s 需要转换的short
* @param index
*/
public static void putShort(byte b[], short s, int index) {
 b[index + 1] = (byte) (s >> 8);
 b[index + 0] = (byte) (s >> 0);
}
/**
* 通过byte数组取到short
*
* @param b
* @param index 第几位开始取
* @return
*/
public static short getShort(byte[] b, int index) {
 return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));
}

2.int与byte数组的互转

/**
*将32位的int值放到4字节的byte数组
* @param num
* @return
*/
public static byte[] intToByteArray(int num) {
 byte[] result = new byte[4];
 result[0] = (byte)(num >>> 24);//取最高8位放到0下标
 result[1] = (byte)(num >>> 16);//取次高8为放到1下标
 result[2] = (byte)(num >>> 8); //取次低8位放到2下标
 result[3] = (byte)(num ); //取最低8位放到3下标
 return result;
}
/**
* 将4字节的byte数组转成一个int值
* @param b
* @return
*/
public static int byteArrayToInt(byte[] b){
 byte[] a = new byte[4];
 int i = a.length - 1,j = b.length - 1;
 for (; i >= 0 ; i--,j--) {//从b的尾部(即int值的低位)开始copy数据
 if(j >= 0)
 a[i] = b[j];
 else
 a[i] = 0;//如果b.length不足4,则将高位补0
 }
 int v0 = (a[0] & 0xff) << 24;//&0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
 int v1 = (a[1] & 0xff) << 16;
 int v2 = (a[2] & 0xff) << 8;
 int v3 = (a[3] & 0xff) ;
 return v0 + v1 + v2 + v3;
}

3.long与byte数组的互转

/**
 * 将64位的long值放到8字节的byte数组
 * @param num
 * @return 返回转换后的byte数组
 */
 public static byte[] longToByteArray(long num) {
 byte[] result = new byte[8];
 result[0] = (byte) (num >>> 56);// 取最高8位放到0下标
 result[1] = (byte) (num >>> 48);// 取最高8位放到0下标
 result[2] = (byte) (num >>> 40);// 取最高8位放到0下标
 result[3] = (byte) (num >>> 32);// 取最高8位放到0下标
 result[4] = (byte) (num >>> 24);// 取最高8位放到0下标
 result[5] = (byte) (num >>> 16);// 取次高8为放到1下标
 result[6] = (byte) (num >>> 8); // 取次低8位放到2下标
 result[7] = (byte) (num); // 取最低8位放到3下标
 return result;
 }
 /**
 * 将8字节的byte数组转成一个long值
 * @param byteArray
 * @return 转换后的long型数值
 */
 public static long byteArrayToInt(byte[] byteArray) {
 byte[] a = new byte[8];
 int i = a.length - 1, j = byteArray.length - 1;
 for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
 if (j >= 0)
 a[i] = byteArray[j];
 else
 a[i] = 0;// 如果b.length不足4,则将高位补0
 }
 // 注意此处和byte数组转换成int的区别在于,下面的转换中要将先将数组中的元素转换成long型再做移位操作,
 // 若直接做位移操作将得不到正确结果,因为Java默认操作数字时,若不加声明会将数字作为int型来对待,此处必须注意。
 long v0 = (long) (a[0] & 0xff) << 56;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
 long v1 = (long) (a[1] & 0xff) << 48;
 long v2 = (long) (a[2] & 0xff) << 40;
 long v3 = (long) (a[3] & 0xff) << 32;
 long v4 = (long) (a[4] & 0xff) << 24;
 long v5 = (long) (a[5] & 0xff) << 16;
 long v6 = (long) (a[6] & 0xff) << 8;
 long v7 = (long) (a[7] & 0xff);
 return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7;
 }

4.float与byte数组的互转

/**
 * float转换byte
 *
 * @param bb
 * @param x
 * @param index
 */
public static void putFloat(byte[] bb, float x, int index) {
 // byte[] b = new byte[4];
 int l = Float.floatToIntBits(x);
 for (int i = 0; i < 4; i++) {
 bb[index + i] = new Integer(l).byteValue();
 l = l >> 8;
 }
}
/**
 * 通过byte数组取得float
 *
 * @param bb
 * @param index
 * @return
 */
public static float getFloat(byte[] b, int index) {
 int l;
 l = b[index + 0];
 l &= 0xff;
 l |= ((long) b[index + 1] << 8);
 l &= 0xffff;
 l |= ((long) b[index + 2] << 16);
 l &= 0xffffff;
 l |= ((long) b[index + 3] << 24);
 return Float.intBitsToFloat(l);
}

5.double与byte数组的互转

 /**
 * double转换byte
 *
 * @param bb
 * @param x
 * @param index
 */
 public static void putDouble(byte[] bb, double x, int index) {
 // byte[] b = new byte[8];
 long l = Double.doubleToLongBits(x);
 for (int i = 0; i < 4; i++) {
 bb[index + i] = new Long(l).byteValue();
 l = l >> 8;
 }
 }
 /**
 * 通过byte数组取得float
 *
 * @param bb
 * @param index
 * @return
 */
 public static double getDouble(byte[] b, int index) {
 long l;
 l = b[0];
 l &= 0xff;
 l |= ((long) b[1] << 8);
 l &= 0xffff;
 l |= ((long) b[2] << 16);
 l &= 0xffffff;
 l |= ((long) b[3] << 24);
 l &= 0xffffffffl;
 l |= ((long) b[4] << 32);
 l &= 0xffffffffffl;
 l |= ((long) b[5] << 40);
 l &= 0xffffffffffffl;
 l |= ((long) b[6] << 48);
 l &= 0xffffffffffffffl;
 l |= ((long) b[7] << 56);
 return Double.longBitsToDouble(l);
 }

6、字符串和十六进制数的互转

写了一个工具类供大家参考:

package com.csc.stringtobyte;
public class StringToByte{
 public static void main(String[] args) {
 String string = new String("hello world!");
 byte[] stringByte = string.getBytes();
 String hexString = bytesToHexString(stringByte);
 System.out.println(hexString);
 byte[] binByte = hexStringToBytes(hexString);
 String result = new String(binByte);
 System.out.println(result);
 }
 /**
 * Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。
 * @param src byte[] data
 * @return hex string
 */ 
 public static String bytesToHexString(byte[] src){
 StringBuilder stringBuilder = new StringBuilder("");
 if (src == null || src.length <= 0) {
 return null;
 }
 for (int i = 0; i < src.length; i++) {
 int v = src[i] & 0xFF;
 String hv = Integer.toHexString(v);
 if (hv.length() < 2) {
 stringBuilder.append(0);
 }
 stringBuilder.append(hv);
 }
 return stringBuilder.toString();
 }
 /**
 * Convert hex string to byte[]
 * @param hexString the hex string
 * @return byte[]
 */
 public static byte[] hexStringToBytes(String hexString) {
 if (hexString == null || hexString.equals("")) {
 return null;
 }
 hexString = hexString.toUpperCase();
 int length = hexString.length() / 2;
 char[] hexChars = hexString.toCharArray();
 byte[] d = new byte[length];
 for (int i = 0; i < length; i++) {
 int pos = i * 2;
 d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
 }
 return d;
 }
 /**
 * Convert char to byte
 * @param c char
 * @return byte
 */
 private static byte charToByte(char c) {
 return (byte) "0123456789ABCDEF".indexOf(c);
 }
}

7、将对象系列化成十六进制的字符串以及将十六机制的字符串反序列化成对象

写了一个工具类供大家参考:

package com.csc.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Locale;
public class SerializeTool {
 /**
 * 将传入的对象系列化后,存入参数string指定的文件,并将序列化后的对象转换成十六进制字符串返回
 * @param object 可序列化的对象
 * @param string 存储文件名
 * @return string 序列化后的对象的十六进制字符串
 * @throws FileNotFoundException
 * @throws IOException
 */
 public static String writeObject(Object object, String strFile)
 throws FileNotFoundException, IOException {
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 //用于将对象转换成byte[]数组的ObjectOutputStream
 ObjectOutputStream oos = new ObjectOutputStream(baos);
 //将对象写入ByteArrayOutputStream
 oos.writeObject(object);
 byte[] bytes = baos.toByteArray();
 //用于将将对象存入文件的ObjectOutputStream
 ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(
 strFile));
 //将对象写入string指定的文件中
 oos2.writeObject(object);
 oos.close();
 oos2.close();
 baos.close();
 return bytesToHexString(bytes);
 }
 /**
 * 将序列化后且用十六进制字符表示的对象反序列化成对象
 * @param hexString 序列化对象的十六进制表示形式的字符串
 * @return 反序列化生成的对象
 * @throws IOException
 * @throws ClassNotFoundException
 */
 public static Object readObject(String hexString) throws IOException,
 ClassNotFoundException {
 byte[] bytes = hexStringToBytes(hexString);
 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
 ObjectInputStream ois = new ObjectInputStream(bais);
 return ois.readObject();
 }
 /**
 * 将传入的byte[]数组转换成十六机制数的字符串
 * @param src 要转换的byte数组
 * @return 返回十六进制的字符串
 */
 private static String bytesToHexString(byte[] src) {
 StringBuilder stringBuilder = new StringBuilder("");
 if (src == null || src.length <= 0) {
 return null;
 }
 for (int i = 0; i < src.length; i++) {
 int v = src[i] & 0xFF;
 //将一个byte的二进制数转换成十六进制字符
 String hv = Integer.toHexString(v);
 //如果二进制数转换成十六进制数高位为0,则加入'0'字符
 if (hv.length() < 2) {
 stringBuilder.append(0);
 }
 stringBuilder.append(hv);
 }
 return stringBuilder.toString();
 }
 /**
 * 将传进来的十六进制表示的字符串转换成byte数组
 * @param hexString
 * @return 二进制表示的byte[]数组
 */
 private static byte[] hexStringToBytes(String hexString) {
 if (hexString == null || hexString.equals("")) {
 return null;
 }
 hexString = hexString.toUpperCase(Locale.getDefault());
 int length = hexString.length() / 2;
 //将十六进制字符串转换成字符数组
 char[] hexChars = hexString.toCharArray();
 byte[] d = new byte[length];
 for (int i = 0; i < length; i++) {
 //一次去两个字符
 int pos = i * 2;
 //两个字符一个对应byte的高四位一个对应第四位
 d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
 }
 return d;
 }
 /**
 * 将传进来的字符代表的数字转换成二进制数
 * @param c 要转换的字符
 * @return 以byte的数据类型返回字符代表的数字的二进制表示形式
 */
 private static byte charToByte(char c) {
 return (byte) "0123456789ABCDEF".indexOf(c);
 }
}


相关推荐

悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)

新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...

高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源

凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...

微服务架构实战:商家管理后台与sso设计,SSO客户端设计

SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...

还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑

在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...

Seata源码—6.Seata AT模式的数据源代理二

大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...

30分钟了解K8S(30分钟了解微积分)

微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...

SpringBoot条件化配置(@Conditional)全面解析与实战指南

一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...

一招解决所有依赖冲突(克服依赖)

背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...

你读过Mybatis的源码?说说它用到了几种设计模式

学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...

golang对接阿里云私有Bucket上传图片、授权访问图片

1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...

spring中的资源的加载(spring加载原理)

最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...

Android资源使用(android资源文件)

Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...

如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)

深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...

@Autowired与@Resource原理知识点详解

springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...

java的redis连接工具篇(java redis client)

在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...