2016-11-18 61 views
1

我想将二进制文件转换为十六进制的ASCII表示形式。这实际上是由于分享我的学术工作时出现了一个奇怪的可移植性问题。动机是,以十六进制表示的文件更容易以ASCII格式打印大值。我有我拥有BASH的独特情况,但可能没有xxd或hexdump。我试图制作一个bash脚本,它接受一个文件,读取一个字节,然后以ASCII十六进制格式输出一个值。我认为printf会是要走的路,但是如果文件有二进制0x30,它会打印出ASCII码“0”。Bash,将字节转换为ASCII而不使用hexdump或xxd

#!/bin/sh 
INPUTFILE=$1 
while IFS= read -r -n1 filechar 
do 
    printf "%02X" "$filechar" 
done < "$INPUTFILE" 
printf "\n" 

我不清楚为什么 “%02X” 没有返回 “30” 为 “0” 的ASCII值。再一次,问题的真正关键是我试图只使用Bash,因为我不能保证任何人都有Bash。更糟糕的是,我正在尝试使用Bash 3.x.任何建议将是最受欢迎的。

+2

打印'0'的原因是因为这是它正在读取的值。您正在读取文件中的每个字符,因此'filechar'值的值为0. printf'二进制不会将您传递给它的字符解释为数字。你不能使用'od -tx $ INPUTFILE'?这应该是POSIX友好的。 – eddiem

+0

@eddiem也许吧。想象一个如此安全以至于无法使用的系统。这就是为什么我试图用bash来做所有事情的原因,就像那样。这只是一个管道噩梦。 “od”是一个不错的选择,因为它永远存在。直到你提到它,我才知道od。如果我能确定每个人都可以运行,我会问管理员。 –

+0

对于某些字符值,您将遇到一些问题:字符0(ASCII NULL)不能在shell变量中表示或作为参数传递,并且127(十六进制7f)以上的字符可能会有问题,具体取决于您的语言环境。 –

回答

0

我想通了一种方法,尽管加载文件到一个字符串可怕。

#!/bin/sh 
FILESTRING=$(<$1) 
for ((i=0;i<${#FILESTRING};i++)); 
do 
    printf %02X \'${FILESTRING:$i:1}; 
done 

在这种方法中,我不需要外部可执行,所以我不担心猛砸以外的任何东西。感谢所有评论过的人。

1

如果字符前面有撇号,则使用该字符的ASCII值。

printf "%02X" "'$filechar" 

但是,我不认为这将适用于非ASCII(> 127)字符。

相关问题