Java修炼终极指南:39. 在字节和十六进制编码字符串之间进行转换
liebian365 2024-10-16 13:08 31 浏览 0 评论
在操纵文件/消息流、执行编码/解码任务、处理图像等应用中,将字节转换为十六进制(反之亦然)是一种常见的操作。Java字节是[-128, +127]范围内的数字,并使用1个有符号字节(8位)表示。十六进制(基数为16)是一个基于16个数字(0、1、2、3、4、5、6、7、8、9、A、B、C、D、E和F)的系统。换句话说,一个字节值的这8位正好可以容纳范围在00到FF之间的2个十六进制字符。十进制 <-> 二进制 <-> 十六进制映射关系如图所示:
图 2.27 - 十进制到二进制到十六进制转换
例如,122在二进制中是01111010。因为0111在十六进制中是7,而1010是A,所以结果是122在十六进制中是7A(也写作0x7A)。那么负字节呢?从上一章我们知道,Java使用正数的二进制补码来表示负数。这意味着-122在二进制中是10000110(保留正数122=1111010的前7位,翻转(1111010)=0000101,加1(0000001)=00000110,并附加符号位1,得到10000110),在十六进制中是0x86。将负数转换为十六进制有多种方法,但我们可以轻松地将较低的4位获取为10000110 & 0xF = 0110,较高的四位为(10000110 >> 4) & 0xF = 1000 & 0xF = 1000(这里,0xF(二进制,1111)掩码仅对负数有用)。由于0110=6,1000=8,所以10000110在十六进制中是0x86。
如果你需要深入了解Java中的位操作,或者你在理解当前主题时遇到问题,那么请考虑阅读《Java完整编码面试指南》的第9章。因此,在代码行中,我们可以依赖这个简单算法和`Character.forDigit(int d, int r)`,它返回给定基数(r)下给定数字(d)的字符表示:
public static String byteToHexString(byte v) {
int higher = (v >> 4) & 0xF;
int lower = v & 0xF;
String result = String.valueOf(
new char[]{
Character.forDigit(higher, 16),
Character.forDigit(lower, 16)}
);
return result;
}
解决这个问题的方法有很多(在捆绑的代码中,你可以看到这种解决方案的另一种风格)。例如,我们知道`Integer.toHexString(int n)`方法返回一个字符串,该字符串表示给定参数的无符号整数在基数16下的值,那么我们只需要对负数应用0xFF(二进制,11111111)掩码即可:
public static String byteToHexString(byte v) {
return Integer.toHexString(v & 0xFF);
}
如果有一种方法我们应该避免,那就是基于`String.format()`的方法。`String.format("%02x ", byte_nr)`这种方法简洁但非常慢!那么反向过程呢?将一个给定的十六进制字符串(例如,7d、09等)转换为字节相当简单。只需获取给定字符串的第一个(d1)和第二个(d2)字符,并应用关系`(byte) ((d1 << 4) + d2)`:
public static byte hexToByte(String s) {
int d1 = Character.digit(s.charAt(0), 16);
int d2 = Character.digit(s.charAt(1), 16);
return (byte) ((d1 << 4) + d2);
}
捆绑的代码中提供了更多示例。如果你依赖第三方库,那么请查看Apache Commons Codec(Hex.encodeHexString())、Guava(BaseEncoding)、Spring Security(Hex.encode())、Bouncy Castle(Hex.toHexString())等,这个列表是开放的。
JDK 17+
从JDK 17开始,我们可以使用`java.util.HexFormat`类。这个类提供了许多静态方法来处理十六进制数,包括`String toHexDigits(byte value)`和`byte[] parseHex(CharSequence string)`。因此,我们可以将字节转换为十六进制字符串,如下所示:
public static String byteToHexString(byte v) {
HexFormat hex = HexFormat.of();
return hex.toHexDigits(v);
}
反之亦然,如下所示:
public static byte hexToByte(String s) {
HexFormat hex = HexFormat.of();
return hex.parseHex(s)[0];
}
在捆绑的代码中,你还可以看到这些解决方案的扩展,用于将字节数组(byte[])转换为字符串,反之亦然。
相关推荐
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
-
明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
-
首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
-
齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...
- Qt界面——搭配QCustomPlot(qt platform)
-
这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
-
老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
-
用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
-
前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...
- 掌握Visual Studio项目配置【基础篇】
-
1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
-
随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...
- Visual Studio Community 2022(VS2022)安装图文方法
-
直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...
- Qt添加MSVC构建套件的方法(qt添加c++11)
-
前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...
- Qt为什么站稳c++GUI的top1(qt c)
-
为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...
- qt开发IDE应该选择VS还是qt creator
-
如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...
- Qt 5.14.2超详细安装教程,不会来打我
-
Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...
- Cygwin配置与使用(四)——VI字体和颜色的配置
-
简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
- Qt界面——搭配QCustomPlot(qt platform)
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
- 掌握Visual Studio项目配置【基础篇】
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
- Visual Studio Community 2022(VS2022)安装图文方法
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)