使用Java 将字节数组转成16进制的形式

概述

在很多场景下,需要进行分析字节数据,但是我们存起来的字节数据一般都是二进制的,这时候就需要我们将其转成16进制的方式方便分析。比如在做音视频的时候,需要看下我们传输的视频h264数据中是否有对应的I帧或者B帧等数据,做ASM插桩的时候,可以使用输出类结构的16进制辅助分析了解问题。测试投屏的时候尤其有用,比如说投屏到电视上后,发现没有画面,或者是画面很卡顿,这时候就需要对我们传输的视频数据做分析,所以我们将视频的数据转成16进制的形式,并且以一定的格式输出,可以很方便的帮助我们定位问题。本文主要介绍如何使用Java将字节数组格式化成16进制的格式并输出。

输出效果展示

在这里插入图片描述上图是以一个class字节码文件的16进制的格式输出,下面就介绍如何将我们的字节数组输出成16进制的格式

代码实现

首先我们定义一个类,用于生成一个class文件,作为我们格式化的对象。读者使用的时候可以是其他数据,只要是字节数组的方式提供就行了,这里仅仅作为演示

public class ASMDemoEntity {private int intNum = 10;private static final String staticString = "hello world";public void fun() {System.out.println("I am fun");}public int add(int a, int b) {return a + b;}public static void main(String[] args) {System.out.println("a+b = " + new ASMDemoEntity().add(1, 2));new ASMDemoEntity().fun();}
}

然后定义一个枚举类,定义我们格式化后的16进制数据的输出样式以及分隔符,如下所示:

public enum HexFormat {// 无分隔符分别展示0,8,16,32列FORMAT_HEX_0("", 0),FORMAT_HEX_8("", 8),FORMAT_HEX_16("", 16),FORMAT_HEX_32("", 32),// 带空格分隔符分别展示0,8,16,32列FORMAT_HEX_SPACE__0(" ", 0),FORMAT_HEX_SPACE_8(" ", 8),FORMAT_HEX_SPACE_16(" ", 16),FORMAT_HEX_SPACE_32(" ", 32);public final String separator; // 分隔符public final int column; // 展示几列HexFormat(String separator, int column) {this.separator = separator;this.column = column;}
}

如上所示:FORMAT_HEX_0就表示展示0列,无分隔符,用一行展示完所有的16进制数据,而FORMAT_HEX_SPACE_32 表示以一个空格做分隔符,展示32列,就如我们本文展示的效果图一样。
接着我们使用一个FileUtil类去读我们生成的.class文件:

public class FileUtil {public static String getFilePath(String relativePath){URL resource = FileUtil.class.getResource("/");String dir = resource == null? "" : resource.getPath();return dir + relativePath;}public static byte[] readBytes(String filePath){File file = new File(filePath);if(!file.exists()){throw new IllegalArgumentException(filePath + "not exist");}InputStream in = null;try {in = Files.newInputStream(file.toPath());in = new BufferedInputStream(in);ByteArrayOutputStream bao = new ByteArrayOutputStream();IOUtil.copy(in,bao);return bao.toByteArray();} catch (IOException e) {e.printStackTrace();}finally {IOUtil.closeIO(in);}return null;}
}

使用一个IOUtil类做复制字节数组和关闭IO流

public class IOUtil {private static final int EOF = -1;private static final int BUFFER_SIZE = 1024 * 4;public static long copy(final InputStream input,final OutputStream output) throws IOException {long count = 0;int n;byte[] buffer = new byte[BUFFER_SIZE];while (EOF != (n = input.read(buffer))) {output.write(buffer, 0, n);count += n;}return count;}public static void closeIO(final Closeable closeable) {if(closeable != null){try {closeable.close();} catch (IOException ignored) {}}}
}

最后使用格式化工具类将字节数组格式化成16进制的样式并按照指定的格式输出

public class HexUtil {public static String hexFormat(byte[] bytes,HexFormat format){String separator = format.separator;int column = format.column;return hexFormat(bytes,separator,column);}private static String hexFormat(byte[] bytes, String separator, int column) {if(bytes == null || bytes.length < 1) {return "";}StringBuilder sb = new StringBuilder();Formatter fm = new Formatter(sb);int length = bytes.length;for (int i = 0; i < length; i++) {int val = bytes[i] & 0xFF;fm.format("%02X",val);if(column > 0 && (i+1) % column == 0){fm.format("%n");}else{fm.format("%s",separator);}}return sb.toString();}
}

在上面代码中的代码是Formatter.format()方法,它的作用是格式化我们的字节数组,我们传入的格式中带有%…X…时表示输出16进制数据,具体的定义如下:
%X: 正常输出16进制数
%NX: 十六进制数,输出N位,如果本身大于N位,正常输出,比如format("%2X",val);表示输出2位16进制数,若本身大于2位,正常输出
%NBX: 十六进制数,输出N位,不足N位就补B,若本身大于N位,就正常输出,比如format("%02X",val);代表输出2位的16进制数,如果不足2位就补0,如果本身大于2位,就正常输出

演示将一个class文件的二进制数据转成16进制数据并格式化后输出:

public class HexFormatMain {public static void main(String[] args) {String relativePath = "org/example/entity/ASMDemoEntity.class";String filePath = FileUtil.getFilePath(relativePath);System.out.println("file path: " + filePath);byte[] bytes = FileUtil.readBytes(filePath);String hex = HexUtil.hexFormat(bytes, HexFormat.FORMAT_HEX_SPACE_32);System.out.println("class文件的16进制: ");System.out.println(hex);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16270.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

纯前端实现将页面数据下载word文档中【包括图片,echarts图,表格,和对话 内容】

亲测真实有效 导出word步骤 在Vue中导出Word文档&#xff0c;可以使用第三方库file-saver和html-docx-js。首先需要安装这两个库&#xff1a; npm install file-saver html-docx-js --save "html-docx-js": "0.3.1","file-saver": "2.0.5…

HADOOP permission denied解决方法(如果你ssh已经确认没问题了)

网上各种方法都是让你去把ssh配置好&#xff0c;让权限chmod 755&#xff0c;但我怎么试都没有用。 并且我的ssh已经能让master登入slave了&#xff0c;这个本来就是没有问题的。不要再尝试了。 有另一种可能的报错&#xff0c;就是你的文件全都被锁住了。可以上slave机上看看…

07、SpringBoot 源码分析 - SpringApplication启动流程七

SpringBoot 源码分析 - SpringApplication启动流程七 初始化基本流程SpringApplication的prepareContext准备上下文postProcessApplicationContext处理applyInitializers初始化器初始化load SpringApplication的refreshContext刷新上下文refreshServletWebServerApplicationCon…

8.什么是HOOK

程序编译的本质是&#xff0c;首先计算机它只能看得懂机器码也就是只能看得懂数字&#xff0c;机器码学起来很费劲然后就创造了编译器这个东西&#xff0c;编译器它懂机器语言所以它可以跟机器沟通&#xff0c;而我们人可以跟编译器沟通&#xff0c;人跟编译器的语言就是各种各…

[Vulnhub]Vulnix 通过NFS挂载+SSH公钥免密登录权限提升

端口扫描 Server IP AddressPorts Open192.168.8.103TCP:22/tcp, 25/tcp, 79/tcp, 110/tcp, 111/tcp, 143/tcp, 512/tcp, 513/tcp, 514/tcp, 993/tcp, 995/tcp, 2049/tcp, 37522/tcp, 42172/tcp, 43219/tcp, 47279/tcp, 54227/tcp $ nmap -p- 192.168.8.103 -sV -sC --min-ra…

P1134 [USACO3.2] 阶乘问题

题目传送门&#xff1a; P1134 [USACO3.2] 阶乘问题 29分代码 #include<bits/stdc.h>using namespace std;int main() {int n;cin>>n;unsigned long long s1;for(int i1;i<n;i){s*i;while(s>10){if(s%100) s/10;else ss%10;}}cout<<s%10<<en…

MyBatis系统学习 - 使用Mybatis完成查询单条,多条数据,模糊查询,动态设置表名,获取自增主键

上篇博客我们围绕Mybatis链接数据库进行了相关概述&#xff0c;并对Mybatis的配置文件进行详细的描述&#xff0c;本篇博客也是建立在上篇博客之上进行的&#xff0c;在上面博客搭建的框架基础上&#xff0c;我们对MyBatis实现简单的增删改查操作进行重点概述&#xff0c;在MyB…

P459 包装类Wrapper

包装类的分类 1&#xff09;针对八种基本数据类型相应的引用类型——包装类。 2&#xff09;有了类的特点&#xff0c;就可以调用类中的方法。 Boolean包装类 Character包装类 其余六种Number类型的包装类 包装类和基本数据类型的相互转换 public class Integer01 {publi…

一文入门ZooKeeper

简介 官网&#xff1a;https://zookeeper.apache.org/index.html 分布式服务协调组件&#xff0c;Google Chubby的开源实现。解决分布式应用中的以下问题&#xff1a;配置管理、命名服务&#xff08;Naming Service&#xff09;、集群管理、统一命名服务、状态同步。 用于解决…

清理这8种微信好友,每年多赚30万,看完让你涨知识!

为什么我们通讯录里面有很多好友&#xff0c;而我们却总是过很清贫&#xff1f;为什么我们通讯录本身有几千的好友&#xff0c;却通过微信好友却无法变现&#xff1f; 在我第二次创业失败的时候&#xff0c;我从整理朋友圈&#xff0c;整理微信通讯录&#xff0c;到清理微信好…

解决文件夹打开出错问题:原因、数据恢复与预防措施

在我们日常使用电脑或移动设备时&#xff0c;有时会遇到一个非常棘手的问题——文件夹打开出错。这种错误可能会让您无法访问重要的文件和数据&#xff0c;给工作和生活带来极大的不便。本文将带您深入了解文件夹打开出错的原因&#xff0c;并提供有效的数据恢复方案&#xff0…

线程池中的阻塞队列和拒接策略

在 Java 中&#xff0c;线程池使用 java.util.concurrent 包中的 ThreadPoolExecutor 来管理线程。ThreadPoolExecutor 提供了几种不同类型的阻塞队列和拒绝策略&#xff0c;以便处理线程池中的任务调度和资源管理。 1. 阻塞队列&#xff08;Blocking Queue&#xff09; 阻塞…

最新Java面试

1.和equals有什么区别&#xff1f; 可以比较基本数据类型和引用数据类型&#xff0c;两端如果是基本数据类型就是判断值是否相同&#xff0c;两端是引用数据类型就是比较内存地址是否相同。 equals()比较引用数据类型&#xff0c;equals在重写之后&#xff0c;判断两个对象的…

【网络协议】应用层协议--HTTP

文章目录 一、HTTP是什么&#xff1f;二、HTTP协议工作过程三、HTTP协议1. fiddler2. Fiddler抓包的原理3. 代理服务器是什么?4. HTTP协议格式1.1 请求1.2 响应 四、认识HTTP的请求1.认识HTTP请求的方法2.认识请求头&#xff08;header&#xff09;3.认识URL3.1 URL是什么&…

CPU 亲和性--sched_setaffinity()函数

sched_setaffinity – 将线程&进程运行在期望的CPU核心上 CPU亲和性 是指进程或线程在运行时倾向于在某个或某些CPU核心上执行&#xff0c;而不是随机或频繁地在不同的核心之间切换。 CPU亲和性利用CPU缓存的局部性&#xff0c;减少缓存失效和进程或线程迁移的开销&#x…

SparkSQL入门

1、SparkSQL是什么&#xff1f; 结论&#xff1a;SparkSQL 是一个即支持 SQL 又支持命令式数据处理的工具 2、SparkSQL 的适用场景&#xff1f; 结论&#xff1a;SparkSQL 适用于处理结构化数据的场景&#xff0c;而Spark 的 RDD 主要用于处理 非结构化数据 和 半结构化数据 …

掌握ASPICE标准:汽车软件测试工程师的专业发展路径

掌握ASPICE标准&#xff1a;汽车软件测试工程师的专业发展路径 文&#xff1a;领测老贺 随着新能源汽车在中国的蓬勃发展&#xff0c;智能驾驶技术的兴起&#xff0c;汽车测试工程师的角色变得愈发关键。这一变革带来了前所未有的挑战和机遇&#xff0c;要求测试工程师不仅要具…

Leetcode 3161. Block Placement Queries

Leetcode 3161. Block Placement Queries 1. 解题思路2. 代码实现 题目链接&#xff1a;3161. Block Placement Queries 1. 解题思路 这一题没有搞定&#xff0c;后来是看了答案才多少有了些思路的&#xff0c;感觉人生真的是玄学拉满&#xff0c;每次我休息一整天完全没有学…

解决git克隆项目出现fatal无法访问git clone https://github.com/lvgl/lvgl.git

Windows 11系统 报错 $ git clone https://github.com/lvgl/lvgl.git Cloning into lvgl... fatal: unable to access https://github.com/lvgl/lvgl.git/: Failed to connect to github.com port 443 after 21141 ms: Couldnt connect to server 解决方法 git运行这两段代码…

创新实训2024.05.26日志:落地基于硬盘的数据库服务

1. 需求任务列表 以下描述易学大模型软件的web应用的功能。 用户注册 用户邮箱&#xff0c;密码&#xff0c;验证码开启官方邮箱&#xff0c;用来发验证码&#xff08;QQ 网易都支持开启smtp协议&#xff0c;找教程&#xff0c;用邮箱不用手机号是为了省买发短信云服务的钱&a…