我想将 JPG 文件转换为int
序列,然后重新转换以再次获取图像。
我的script.sh
是这样的:
FILE=$(cat $2)
TOTAL=$(echo ${#FILE} - 1 | bc);
for j in $(seq 0 $TOTAL)
do
printf "%d " "'${FILE:j:1}" >> sai.out
done
显然工作正常。所以sai.out
收到类似的东西32767 32767 32767 32767 16 74 70 73 70 1 1 1 1 32767 32767 67 8 ...
。
使用相同的代码但输入文本文件,可以通过 ASCII 表和打印轻松进行解码%c
。
问题是:如何从我的sai.out
文件中再次获取图像文件?
答案1
POSIXly:
od -An -vtu1 < file > file.encoded
v
文件的每个字节都被编码为带有地址u
的无符号十进制数。n
A
要解码,使用一些awk
实现(例如gawk
或有效mawk
的printf("%c", 0)
实现):
awk '{for (i = 1; i <= NF; i++) printf "%c", $i}' < file.encoded > file
关于为什么你的方法不起作用的一些注意事项:
- shell 无法
zsh
在其变量中存储任意数据(尤其是 NUL 字节)。 - 类似 Bourne 的 shell 中的命令替换会去除尾随换行符(在大多数系统上为 0xa 字节)
- 你需要在类似 Bourne 的 shell 中引用变量,除了
zsh
- 在具有
${var:offset:length}
ksh93
运算符 (ksh93
,bash
,zsh
,mksh
) 的 shell 中,offset
和length
以字符数而不是字节数表示(但是 UTF-8 是唯一受支持且仅在启用mksh
该选项时才支持的多字节字符编码)。utf8-mode
printf %d \'x
返回字符的代码点编号。这只是单字节字符集中的字节值。在这里,您可能正在使用bash
并且正在使用 UTF-8 编码作为语言环境bash
给出printf
不构成有效字符一部分的字节的随机值。- text 被定义为文本行的序列,它们本身是非 NUL 的序列人物(因此仅限于形成有效字符的字节序列)其长度(以数量为单位)字节包括换行符)不超过
LINE_MAX
(请参阅getconf LINE_MAX
)并由换行符分隔。因此,除了非常小的 jpg 文件之外,您sai.out
最终将不是有效的文本,并且您无法保证它会被文本实用程序正常处理(od
这里每行仅输出几个数字)。
答案2
如果十六进制是有效的整数表示形式,则 xxd 会为您完成工作:
xxd -p image.jpg > image.hex
并且,要恢复为图像:
xxd -p -r image.hex > image-copy.jpg
答案3
我的回答是基于Arrow的提示。我不是这方面的专家,sed
所以我相信有比这更好的解决方案,但目前有效。
策略是将我的文件转换为十六进制xxd
,然后将十六进制转换为整数。
编码:
xxd -p $1 | sed 's/.\{2\}/& /g' | sed 's/[^ ]* */0x&/g' | awk '{ for(i=1;i<=NF;i++) printf("%i ",$i); print ""; }' > $2
解码:
awk '{ for(i=1;i<=NF;i++) printf("%02x ",$i); print ""; }' $IN > $OUT
xxd -p -r $OUT $OUT_IMAGE_NAME.jpg
rm $OUT