别找了,这个命令让你在字符串和十六进制间自由转换
做开发,尤其是嵌入式开发,要不过去过去曾经,要不现在,或者将来一定会遇到十六进制字符串和二进制文件之间转换的操作。像这样的情形:有一个十六进制字符串,需要转换为二进制文件;有一个二进制文件,需要转换为十六进制数组;有一个十六进制数组,需要转换为二进制文件;有一个二进制文件,需要转换为十六进制字符串;最多就是前两种情形。不管你们是不是经常遇到,反正我是。以前到处搜,没找到中意的,后来干脆自己用pyt
做开发,尤其是嵌入式开发,要不过去过去曾经,要不现在,或者将来一定会遇到十六进制字符串和二进制文件之间转换的操作。
像这样的情形:
- 有一个十六进制字符串,需要转换为二进制文件;
- 有一个二进制文件,需要转换为十六进制数组;
- 有一个十六进制数组,需要转换为二进制文件;
- 有一个二进制文件,需要转换为十六进制字符串;
最多就是前两种情形。不管你是不是经常遇到,反正我是。
以前到处搜,没找到中意的,后来干脆自己用python写了个脚本将二进制转数组。到后来发现,都是浪费时间,linux自带工具就能满足这样的需求,甚至更多。
好吧,废话不多说了。一句话,命令行工具xxd能让你实现这种自由。要是觉得太啰嗦,还请直接转到第7节看总结。
1. 十六进制字符串转换为二进制文件
- 例一
我有一个十六进制字符串,包含字母数字大小写,想转换成二进制文件。
# 字符串: ABCDEF0123456789abcdef0123456789
# 1. 转换
$ echo -n "ABCDEF0123456789abcdef0123456789" | xxd -r -ps > test11.bin
# 2. 检查
$ xxd -g 1 test11.bin
0000000: ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 ....#Eg.....#Eg.
- 例二
例一中的情形太简单了,上个复一点的,这次是完整的十六进制字符串,字符带有0x前缀,还有空格,想转换成二进制文件。
# 字符串: 0xAB 0xCD 0xEF 0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF 0x01 0x23 0x45 0x67 0x89
# 转换
$ echo -n "0xAB 0xCD 0xEF 0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF 0x01 0x23 0x45 0x67 0x89" | xxd -r -ps > test12.bin
# 检查
$ xxd test12.bin
0000000: abcd ef01 2345 6789 abcd ef01 2345 6789 ....#Eg.....#Eg.
- 例三
升级版,这次的字符串中不仅有0x前缀,带空格,还有逗号","分割,一样不在话下:
# 字符串: "0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89"
# 转换
$ echo -n "0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89" | xxd -r -ps > test13.bin
# 检查
$ xxd test13.bin
0000000: abcd ef01 2345 6789 abcd ef01 2345 6789 ....#Eg.....#Eg.
就一条命令,带有字母数字大小写,带空格0x前缀和逗号的字符串,通通一行搞定,就问你服不服。
2. 二进制文件转换成十六进制数组
用到这个操作的地方实在是太多了,常常需要将各种点阵字库,各种图片,各种固件转换成代码。
So easy! 一秒搞定!
- 例四
把前面例一中的二进制文件转换成数组。
方式一:
# 文件
$ xxd -g 1 test11.bin
0000000: ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 ....#Eg.....#Eg.
# 数组
$ xxd -i test11.bin
unsigned char test11_bin[] = {
0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
0x23, 0x45, 0x67, 0x89
};
unsigned int test11_bin_len = 16;
方式二:
# 文件
$ xxd -g 1 test11.bin
0000000: ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 ....#Eg.....#Eg.
# 数组
$ xxd -i < test11.bin
0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
0x23, 0x45, 0x67, 0x89
这两种方式有点小差别,看出来区别在哪里了吗?不管怎样,就问你爽不爽?
3. 十六进制数组转换成二进制文件
- 例五
其实这种方式在例三中已经说过了,对头不?
# 从数组中拿到的字符串
$ echo -n " 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0xAB, 0xCD, 0xEF, 0x98, 0x76, 0x54, 0x32, 0x10
" | xxd -r -ps > test31.bin
# 检查文件
$ hexdump -Cv test31.bin
00000000 aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 |........"3DUfw..|
00000010 01 23 45 67 89 ab cd ef ab cd ef 98 76 54 32 10 |.#Eg........vT2.|
00000020
4. 二进制文件转换为十六进制字符串
- 例六
我有个二进制文件,想转换成对应的字符串。
就是把前面例一中的二进制文件还原成字符串
# 二进制文件
$ xxd -g 1 test11.bin
0000000: ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 ....#Eg.....#Eg.
# 转换成小写字符串
$ xxd -ps test11.bin
abcdef0123456789abcdef0123456789
# 转换成大写字符串
$ xxd -ps -u test11.bin
ABCDEF0123456789ABCDEF0123456789
5. 更多骚操作,十六进制转二进制位串
- 例七,查看文件的二进制位串
$ xxd -g 1 test11.bin
0000000: ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 ....#Eg.....#Eg.
$ xxd -b test11.bin
0000000: 10101011 11001101 11101111 00000001 00100011 01000101 ....#E
0000006: 01100111 10001001 10101011 11001101 11101111 00000001 g.....
000000c: 00100011 01000101 01100111 10001001 #Eg.
$ xxd -g 1 -c 8 test11.bin
0000000: ab cd ef 01 23 45 67 89 ....#Eg.
0000008: ab cd ef 01 23 45 67 89 ....#Eg.
rocky@guyongqiangx:/public/xxd$ xxd -b -c 8 test11.bin
0000000: 10101011 11001101 11101111 00000001 00100011 01000101 01100111 10001001 ....#Eg.
0000008: 10101011 11001101 11101111 00000001 00100011 01000101 01100111 10001001 ....#Eg.
6. 不能再爽了,还能直接修改二进制文件
- 例八,修改二进制文件
直接以指定偏移量的方式修改文件,下面这个命令将0x12开始的4个字节替换为"0xAA 0xBB 0xCC 0xDD":
# 修改前
$ xxd test31.bin
0000000: aabb ccdd eeff 0011 2233 4455 6677 8899 ........"3DUfw..
0000010: 0123 4567 89ab cdef abcd ef98 7654 3210 .#Eg........vT2.
# 替换0x12开始的4个字节为 AA BB CC DD
$ echo -n "0012: AABBCCDD" | xxd -r - test31.bin
# 修改后
$ xxd test31.bin
0000000: aabb ccdd eeff 0011 2233 4455 6677 8899 ........"3DUfw..
0000010: 0123 aabb ccdd cdef abcd ef98 7654 3210 .#..........vT2.
命令
echo -n "0012: AABBCCDD" | xxd -r - test31.bin
中有个小小的-
,千万不要漏掉了。还有,修改前记得要备份!哭的时候,不要说我没提醒过,哈哈哈~~
7. 总结
- 十六进制字符串转换成二进制文件
$ echo -n "ABCDEF0123456789abcdef0123456789" | xxd -r -ps > test11.bin
- 二进制文件转换成十六进制数组
$ xxd -i test11.bin
unsigned char test11_bin[] = {
0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
0x23, 0x45, 0x67, 0x89
};
unsigned int test11_bin_len = 16;
- 二进制文件转换成十六进制字符串
$ xxd -ps test11.bin
abcdef0123456789abcdef0123456789
掌握了这3条命令,十六进制和二进制转化,你自由了。
剩下的时间可用来泡妞,可用来划水,可用来摸鱼,还可以用来解更多的bug,这一切的一切,难道不香吗?
xxd工具,你值得拥有。
最近会重新开始更新公众号,所以来一波硬广。
洛奇工作中常常会遇到自己不熟悉的问题,这些问题可能并不难,但因为不了解,找不到人帮忙而瞎折腾,往往导致浪费几天甚至更久的时间。
所以我组建了几个微信讨论群(记得微信我说加哪个群,如何加微信见后面),欢迎一起讨论:
- 一个密码编码学讨论组,主要讨论各种加解密,签名校验等算法,请说明加密码学讨论群。
- 一个Android OTA的讨论组,请说明加Android OTA群。
- 一个git和repo的讨论组,请说明加git和repo群。
在工作之余,洛奇尽量写一些对大家有用的东西,如果洛奇的这篇文章让您有所收获,解决了您一直以来未能解决的问题,不妨赞赏一下洛奇,这也是对洛奇付出的最大鼓励。扫下面的二维码赞赏洛奇,金额随意:
洛奇自己维护了一个公众号“洛奇看世界”,一个很佛系的公众号,不定期瞎逼逼。公号也提供个人联系方式,一些资源,说不定会有意外的收获,详细内容见公号提示。扫下方二维码关注公众号:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)