ddを使わずに上下1Byte入れ替えをするプログラムを考えてみます。
まずは実験用のバイナリ生成。
takk@deb9:~/tmp$ seq 10 | perl -ne 'print chr'>in.bin takk@deb9:~/tmp$ hd in.bin 00000000 01 02 03 04 05 06 07 08 09 0a |..........| 0000000a takk@deb9:~/tmp$
まずはPerlから。pack/unpack使います。
takk@deb9:~/tmp$ cat -n swab.pl
1 open(FH,"<".shift);
2 while(read(FH,$dat,2)){
3 print pack("S",unpack("n",$dat));
4 }
takk@deb9:~/tmp$
手っ取り早いのはエンディアン変換です。unpackでテキストに変換し、packで戻すときに上下1Byte入れ替えします。
実行結果です。
takk@deb9:~/tmp$ perl swab.pl in.bin | hd 00000000 02 01 04 03 06 05 08 07 0a 09 |..........| 0000000a takk@deb9:~/tmp$
次はruby。rubyでもエンディアン変換するだけです。
takk@deb9:~/tmp$ cat -n swab.rb
1 a=File.binread('in.bin').unpack('v*')
2 print a.pack('n*')
takk@deb9:~/tmp$
実行結果。
takk@deb9:~/tmp$ ruby swab.rb | hd 00000000 02 01 04 03 06 05 08 07 0a 09 |..........| 0000000a takk@deb9:~/tmp$
でも結局、PerlでもRubyでもバイナリをそのまま処理してません。変換が入ってます。
直接処理するには、やはりC言語でしょうか。
takk@deb9:~/tmp$ cat -n swab.c
1 #include <stdio.h>
2
3 int main(int argc, char* argv[])
4 {
5 int c,pre=-1;
6 FILE *fp;
7 fp=fopen(argv[1],"r");
8
9 while((c=fgetc(fp)) != -1){
10 if(pre != -1){
11 printf("%c%c",c,pre);
12 pre=-1;
13 }else
14 pre=c;
15 }
16 if(pre != -1)
17 printf("%c",pre);
18
19 return 0;
20 }
21
takk@deb9:~/tmp$
スクリプトと違いプログラムは長くなってしまいますが、余計な変換が入らない分スッキリしています。
結果です。
takk@deb9:~/tmp$ gcc swab.c takk@deb9:~/tmp$ ./a.out in.bin | hd 00000000 02 01 04 03 06 05 08 07 0a 09 |..........| 0000000a takk@deb9:~/tmp$



コメント