免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10088 | 回复: 12

请问如何以十六进制字符的形式搜索指定字符串的偏移位置? [复制链接]

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2011-06-27 10:43 |显示全部楼层
本帖最后由 andkylee 于 2011-06-27 10:45 编辑

有个问题,请教一下!
如何以十六进制字符的形式搜索指定字符串的偏移位置?
比如:
一个二进制文件:test_Hex.bin的内容为:

andkylee@ubuntu:~$ hexdump -C test_Hex.bin
00000000  01 00 00 00 02 00 00 00  41 42 43 44 03 00 00 00  |........ABCD....|
00000010

该文件仅有16字节的内容,红色部分标注。其中前0-3字节的01000000表示整数1,第4-7字节的02000000表示整数2,第8-11字节的41424344表示字符串ABCD,第12-15字节的03000000表示整数3.
字符串ABCD在文件test_Hex.bin中的偏移量为:8。请问如何用shell判断出来指定字符串ABCD在文件test_Hex.bin中的偏移量?

我研究过一些16进制查看命令:hexdump,xxd,od,发现这些工具没有搜索指定内容的功能。我google到的文档:
我使用过的Linux命令之hexdump - ”十六“进制查看器

如何以十六进制的形式读unix平台下的文件系统与裸设备文件

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
发表于 2011-06-27 12:23 |显示全部楼层
回复 1# andkylee

供你参考:
  1. echo '00000000  01 00 00 00 02 00 00 00  41 42 43 44 03 00 00 00
  2. 00000000  01 00 00 00 02 00 00 00  41 42 43 44 03 00 00 00' |\
  3. while read line
  4. do
  5.    x=0
  6.    for i in `echo $line`
  7.    do
  8.       printf -v str "\x"$i
  9.       ((x++))
  10.       [ $str ] && [ $str = "A" ] && echo $((x-=2))
  11.    done
  12. done
  13. 8
  14. 8
复制代码

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2011-06-27 14:51 |显示全部楼层
本帖最后由 andkylee 于 2011-06-27 14:53 编辑

回复 2# yinyuemi


    谢谢你的回复。

你的代码中循环遇到A就返回偏移位置而没有继续判断后面是否匹配BCD这三个字母。

抱歉,可能我没有说清楚文件test_Hex.bin的具体内容。

文件test_Hex.bin的内容:
01000000020000004142434403000000
以十六进制形式显示,16个字节。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2011-06-27 15:31 |显示全部楼层
回复  yinyuemi


    谢谢你的回复。

你的代码中循环遇到A就返回偏移位置而没有继续判断后面是否匹 ...
andkylee 发表于 2011-06-27 14:51



$ hexdump -C test_Hex.bin
00000000  01 00 00 00 02 00 00 00  41 42 43 44 03 00 00 00  |........ABCD....|
00000010

$ awk '{print index($0,"ABCD")}' test_Hex.bin
9

$ awk '{print index($0,"ABCD")-1}' test_Hex.bin
8

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
发表于 2011-06-27 16:01 |显示全部楼层
回复 3# andkylee
  1. cat index.sh
  2. #!/bin/bash

  3. filename=$1
  4. cat $filename |while read line
  5. do
  6.         str=" "
  7.         for i in ${line:9}
  8.         do
  9.                 if [ $i -lt 41 ] && [ ${#i} -eq 2 ]
  10.                 then
  11.                         printf "\x0"$i
  12.                 else
  13.                         printf "\x"$i
  14.                 fi
  15.         done
  16.         printf "\n"
  17. done |\
  18. awk '{print (index($0,"ABCD")-1)/2}'

  19. chmod +x index.sh
  20. ./index.sh urfile
复制代码

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2011-06-27 17:22 |显示全部楼层
回复 4# jason680


    谢谢你的回复。
使用awk好像有些问题,awk是用换行\x0a作为记录的分割的。实际上,二进制文件中的字符\0xoa不一定表示换行的意思。
比如文件test_Hex.bin的内容变成:
010000000a0000004142434403000000

执行:awk '{print index($0,"ABCD")-1}' test_Hex.bin
会返回2条记录:
-1
3

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2011-06-27 17:26 |显示全部楼层
本帖最后由 jason680 于 2011-06-27 17:52 编辑
回复  jason680


    谢谢你的回复。
使用awk好像有些问题,awk是用换行\x0a作为记录的分割的。实际上 ...
andkylee 发表于 2011-06-27 17:22


给真正的数值,才会有真正解答吧....

$ hexdump -C test_Hex.bin
00000000  01 00 00 00 0a 00 00 00  41 42 43 44 03 00 00 00  |........ABCD....|
00000010

$ awk '{n=index($0,"ABCD");if(n)print t+n-1;else t=t+length($0)+1}' test_Hex.bin
8

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2011-06-28 11:18 |显示全部楼层
回复 5# yinyuemi


    谢谢您的回复。 你这个方法不行啊。 返回-0.5

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2011-06-28 11:41 |显示全部楼层
回复 7# jason680


    谢谢。你这个方法可以。
在awk内index函数也可以显示"\x41\x42\x43\x44"表示“ABCD”。
awk '{n=index($0,"\x41\x42\x43\x44");if(n)print t+n-1;else t=t+length($0)+1}' test_Hex.bin 这条命令也是可以的。

但是,发现两个问题,awk内的index只返回该行匹配的第一个位置;
返回的第二个匹配的位置是错误的(因为前一个匹配后没有给t赋值)。

例子:
  1. # awk '{n=index($0,"\x00\x00");if(n)print t+n-1;else t=t+length($0)+1}' test_Hex.bin
  2. 1
  3. 0
复制代码
另外,我感觉二进制文件一般不是用\x0a作为行分割的,或者说二进制文件就没有换行的概念。
我用上面的命令处理一个200M的数据文件时速度不是很快。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2011-06-28 12:05 |显示全部楼层
想起某人说的一句话: 有完整的问题,才会得到完整的答案....
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP