java 用于反转字节顺序/更改字节序的命令行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6438099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Command-line to reverse byte order/change endianess
提问by Alexander Torstling
I'm hacking around in some scripts trying to parse some data written by Javas DataOutputStream#writeLong(...)
. Since java always seems to write big endian, I have a problem feeding the bytes to od
. This is due to the fact that od
always assumes that the endianess matches the endianess of the arch that you are currently on, and I'm on a little endian machine.
我正在尝试解析一些由 Javas 编写的数据的脚本DataOutputStream#writeLong(...)
。由于 java 似乎总是写大端,因此我在将字节提供给od
. 这是因为od
始终假设字节序与您当前所在的拱门的字节序相匹配,而我使用的是小型字节序机器。
I'm looking for an easy one-liner to reverse the byte order. Let's say that you know that the last 8 bytes of a file is a long written by the aforementioned writeLong(...)
method. My current best attempt to print this long is
我正在寻找一种简单的单行来反转字节顺序。假设您知道文件的最后 8 个字节是由上述writeLong(...)
方法写入的 long 。我目前打印这么长的最佳尝试是
tail -c 8 file | tac | od -t d8
, but tac
only seems to work on text (fair enough). I've found some references to dd conv=swab
, but this only swaps bytes in pairs, and cannot reverse these eight bytes.
,但tac
似乎只适用于文本(足够公平)。我发现了一些对 的引用dd conv=swab
,但这只是成对交换字节,不能反转这八个字节。
Does anyone know a good one-liner for this?
有没有人知道一个好的单线?
采纳答案by Alexander Torstling
Resorted to Perl in the end. Used a one-liner which I found at PERL One Liners:
最后求助于Perl。使用了我在PERL One Liners找到的单线:
tail -c 8 file | perl -0777e 'print scalar reverse <>' | od -t d8
The 0777
separator char was a bit puzzling to me, but thispage at debian admin seems to suggest that it is a placeholder for 'no record separator', triggering a complete reverse byte-per byte.
该0777
分离器字符是一个有点令人费解给我,但这个页面在Debian的管理员似乎表明,它是“无记录分隔符”占位符,引发了完整的反向字节每字节。
Other suggestions are welcome.
欢迎其他建议。
EDIT: Found another command in a comment to tac.c, which I downloaded from GNU coreutils:
编辑:在我从 GNU coreutils 下载的 tac.c 的评论中找到了另一个命令:
Copy each FILE, or the standard input if none are given or when a FILE name of "-" is encountered, to the standard output with the order of the records reversed. The records are separated by instances of a string, or a newline if none is given. By default, the separator string is attached to the end of the record that it follows in the file.
Options: -b, --before The separator is attached to the beginning of the record that it precedes in the file. -r, --regex The separator is a regular expression. -s, --separator=separator Use SEPARATOR as the record separator.
To reverse a file byte by byte, use (in bash, ksh, or sh): tac -r -s '.\| ' file
将每个 FILE 或标准输入(如果没有给出或遇到 FILE 名称“-”)复制到标准输出,记录顺序颠倒。记录由字符串的实例分隔,如果没有给出,则用换行符分隔。默认情况下,分隔符字符串附加到它在文件中跟随的记录的末尾。
选项:-b、--before 分隔符附加到文件中它前面的记录的开头。-r, --regex 分隔符是正则表达式。-s, --separator=separator 使用 SEPARATOR 作为记录分隔符。
要逐字节反转文件,请使用(在 bash、ksh 或 sh 中): tac -r -s '.\| ' 文件
回答by Marc
You could use objcopy:
你可以使用objcopy:
$ objcopy -I binary -O binary --reverse-bytes=num inputfile.bin outputfile.bin
where num is either 2 or 4.
其中 num 是 2 或 4。
回答by pixelbeat
Note the next version of GNU coreutils (>= 8.23) will add the --endian={little,big} option to the od command
请注意下一版本的 GNU coreutils (>= 8.23) 将在 od 命令中添加 --endian={little,big} 选项
回答by Anton Chevychalov
Used dd, Luke!
用过 dd,卢克!
dd if=sourcefile of=resultfile conv=swab
回答by Brian Carcich
BASH:
巴什:
od -b -v -w8 | while read pfx b8 ; do [ "$b8" ] && echo -n 12345678 | tr 87654321 \${b8// /\} ; done
To be a bit more robust depending on the output style of od
, it may need to compress spaces ( insert "| sed 's/ */ /g'"
after the w8
).
为了根据 的输出样式更加健壮od
,它可能需要压缩空格(在"| sed 's/ */ /g'"
之后插入w8
)。
回答by Mark Lakata
I came up with this Perl one-liner to convert 4-byte integers from one endianness to another:
我想出了这个 Perl one-liner 来将 4 字节整数从一个字节序转换为另一个字节序:
$ perl -e 'open F,shift; do { read(F,$a,4); print scalar reverse($a);} while(!eof(F));' bigend.bin > littlend.bin
That probably works fine on real Linux machines, but Cygwin bit me in the end, treating the binary file as text and inserting a 0x0D (aka CR) before each 0x0A byte (aka newline). But if you pipe to cat -
, it seems to leave it alone. This works for me:
这可能在真正的 Linux 机器上运行良好,但 Cygwin 最后咬了我,将二进制文件视为文本并在每个 0x0A 字节(又名换行符)之前插入一个 0x0D(又名 CR)。但是,如果您使用管道cat -
,它似乎就不管它了。这对我有用:
$ perl -e 'open F,shift; do { read(F,$a,4); print scalar reverse($a);} while(!eof(F));' bigend.bin | cat - > littlend.bin