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$
コメント