12 January 2020

(Linux) ファイルのバイナリダンプとテキスト相互変換

バイナリファイルを16進数ダンプしたり、ダンプされたテキストファイルを元のバイナリファイルに戻したり…

odコマンド (バイナリ → テキスト)

-t x1 : 16進数ダンプ(1バイト単位)
-t x2 : 16進数ダンプ(2バイト単位)
-t z : 右側にテキスト領域あり
-A x : 左側のアドレスを16進数で表示
-A n : 左側のアドレスを表示しない(None)
-w 16 : 1行16バイトで改行する

$ od -tx1z -Ax data.txt
000000 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36  >........xxd - 16<
000010 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92  > ...............<
000020 e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3  >................<
000030 80 81 e5 85 83 e3 81 ab e6 88 bb e3 81 97 e3 81  >................<
000040 9f e3 82 8a e3 80 82 0a e6 9b b8 e5 bc 8f 0a 78  >...............x<
000050 78 64 20 2d 68 5b 65 6c 70 5d 0a 78 78 64 20 5b  >xd -h[elp].xxd [<
000060 6f 70 74 69 6f 6e 73 5d 20 5b 69 6e 66 69 6c 65  >options] [infile<
000070 20 5b 6f 75 74 66 69 6c 65 5d 5d 0a 78 78 64 20  > [outfile]].xxd <
$ od -tx1 -Ax data.txt
000000 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36
000010 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92
000020 e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3
000030 80 81 e5 85 83 e3 81 ab e6 88 bb e3 81 97 e3 81
000040 9f e3 82 8a e3 80 82 0a e6 9b b8 e5 bc 8f 0a 78
000050 78 64 20 2d 68 5b 65 6c 70 5d 0a 78 78 64 20 5b
000060 6f 70 74 69 6f 6e 73 5d 20 5b 69 6e 66 69 6c 65
000070 20 5b 6f 75 74 66 69 6c 65 5d 5d 0a 78 78 64 20
$ od -tx1 -An data.txt
 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36
 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92
 e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3
 80 81 e5 85 83 e3 81 ab e6 88 bb e3 81 97 e3 81
 9f e3 82 8a e3 80 82 0a e6 9b b8 e5 bc 8f 0a 78
 78 64 20 2d 68 5b 65 6c 70 5d 0a 78 78 64 20 5b
 6f 70 74 69 6f 6e 73 5d 20 5b 69 6e 66 69 6c 65
 20 5b 6f 75 74 66 69 6c 65 5d 5d 0a 78 78 64 20

-j01234 : ファイル先頭から01234バイトシークした位置より始める
-N01234 : 01234バイト処理する(ダンプする)

ファイル先頭から0x20バイトをダンプする

$ od -tx1 -Ax -N0x20 data.txt
000000 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36
000010 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92
000020

ファイル先頭から0x10バイトシークし、そこから0x20バイトをダンプする

$ od -tx1 -Ax -j0x10 -N0x20 data.txt
000010 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92
000020 e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3
000030

xxdコマンド (バイナリ → テキスト)

-g1 : 1バイト毎に区切る
-c16 : 1行16バイトで改行する
-u : 16進数表記に大文字のA〜Fを使う
-p : プレーン表示

$ xxd -g1 data.txt
00000000: 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36  ........xxd - 16
00000010: 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92   ...............
00000020: e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3  ................
00000030: 80 81 e5 85 83 e3 81 ab e6 88 bb e3 81 97 e3 81  ................
00000040: 9f e3 82 8a e3 80 82 0a e6 9b b8 e5 bc 8f 0a 78  ...............x
00000050: 78 64 20 2d 68 5b 65 6c 70 5d 0a 78 78 64 20 5b  xd -h[elp].xxd [
00000060: 6f 70 74 69 6f 6e 73 5d 20 5b 69 6e 66 69 6c 65  options] [infile
00000070: 20 5b 6f 75 74 66 69 6c 65 5d 5d 0a 78 78 64 20   [outfile]].xxd 
$ xxd -g1 -u data.txt
00000000: 0A E5 90 8D E5 89 8D 0A 78 78 64 20 2D 20 31 36  ........xxd - 16
00000010: 20 E9 80 B2 E3 83 80 E3 83 B3 E3 83 97 E3 82 92   ...............
00000020: E4 BD 9C E6 88 90 E3 81 97 E3 81 9F E3 82 8A E3  ................
00000030: 80 81 E5 85 83 E3 81 AB E6 88 BB E3 81 97 E3 81  ................
00000040: 9F E3 82 8A E3 80 82 0A E6 9B B8 E5 BC 8F 0A 78  ...............x
00000050: 78 64 20 2D 68 5B 65 6C 70 5D 0A 78 78 64 20 5B  xd -h[elp].xxd [
00000060: 6F 70 74 69 6F 6E 73 5D 20 5B 69 6E 66 69 6C 65  options] [infile
00000070: 20 5B 6F 75 74 66 69 6C 65 5D 5D 0A 78 78 64 20   [outfile]].xxd 
$ xxd -p -c16 data.txt
0ae5908de5898d0a787864202d203136
20e980b2e38380e383b3e38397e38292
e4bd9ce68890e38197e3819fe3828ae3
8081e58583e381abe688bbe38197e381
9fe3828ae380820ae69bb8e5bc8f0a78
7864202d685b656c705d0a787864205b
6f7074696f6e735d205b696e66696c65
205b6f757466696c655d5d0a78786420

0x10バイト(16バイト)シークした位置から後をダンプする場合

$ xxd -g1 -s0x10 data.txt
00000010: 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92   ...............
00000020: e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3  ................
00000030: 80 81 e5 85 83 e3 81 ab e6 88 bb e3 81 97 e3 81  ................
00000040: 9f e3 82 8a e3 80 82 0a e6 9b b8 e5 bc 8f 0a 78  ...............x
00000050: 78 64 20 2d 68 5b 65 6c 70 5d 0a 78 78 64 20 5b  xd -h[elp].xxd [
00000060: 6f 70 74 69 6f 6e 73 5d 20 5b 69 6e 66 69 6c 65  options] [infile
00000070: 20 5b 6f 75 74 66 69 6c 65 5d 5d 0a 78 78 64 20   [outfile]].xxd 

ファイルの最後から0x10バイト(16バイト)ダンプする場合

$ xxd -g1 -s-0x10 data.txt
00000250: 81 a7 e3 81 8d e3 81 be e3 81 99 e3 80 82 20 0a  .............. .

ファイルの先頭から0x10バイトシークした位置より、0x20バイトをダンプする

$ xxd -g1 -s0x10 -l0x20 data.txt
00000010: 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92   ...............
00000020: e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3  ................

xxdコマンド (バイナリ → unsigned char 配列形式)

ソースコードにバイナリデータを取り込む場合、便利な出力形式です。1行の長さを -c で制御できます。

$ xxd -i -c 16 data.txt
unsigned char data_txt[] = {
  0x0a, 0xe5, 0x90, 0x8d, 0xe5, 0x89, 0x8d, 0x0a, 0x78, 0x78, 0x64, 0x20, 0x2d, 0x20, 0x31, 0x36,
  0x20, 0xe9, 0x80, 0xb2, 0xe3, 0x83, 0x80, 0xe3, 0x83, 0xb3, 0xe3, 0x83, 0x97, 0xe3, 0x82, 0x92,
  0xe4, 0xbd, 0x9c, 0xe6, 0x88, 0x90, 0xe3, 0x81, 0x97, 0xe3, 0x81, 0x9f, 0xe3, 0x82, 0x8a, 0xe3,
  0x80, 0x81, 0xe5, 0x85, 0x83, 0xe3, 0x81, 0xab, 0xe6, 0x88, 0xbb, 0xe3, 0x81, 0x97, 0xe3, 0x81,
  0x9f, 0xe3, 0x82, 0x8a, 0xe3, 0x80, 0x82, 0x0a, 0xe6, 0x9b, 0xb8, 0xe5, 0xbc, 0x8f, 0x0a, 0x78,
  0x78, 0x64, 0x20, 0x2d, 0x68, 0x5b, 0x65, 0x6c, 0x70, 0x5d, 0x0a, 0x78, 0x78, 0x64, 0x20, 0x5b,
  0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5d, 0x20, 0x5b, 0x69, 0x6e, 0x66, 0x69, 0x6c, 0x65,
  0x20, 0x5b, 0x6f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x5d, 0x5d, 0x0a, 0x78, 0x78, 0x64, 0x20,
〜 略 〜
  0x81, 0xa7, 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0xbe, 0xe3, 0x81, 0x99, 0xe3, 0x80, 0x82, 0x20, 0x0a
};
unsigned int data_txt_len = 608;

xxdで出力したダンプファイルを、xxdでバイナリファイルに戻す

利用したテキストダンプの形式
0ae5908de5898d0a787864202d203136
20e980b2e38380e383b3e38397e38292
e4bd9ce68890e38197e3819fe3828ae3
$ xxd -p -c16 data.txt | xxd -p -r > data.rebuild 
$ cmp --verbose data.txt data.rebuild 

odで出力したダンプファイルを、xxdでバイナリファイルに戻す

-r : ダンプファイルを元に戻す(再バイナリ化)
-r -p : プレーン形式のダンプファイルを元に戻す(再バイナリ化)

利用したテキストダンプの形式
 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36
 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92
 e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3
$ od -tx1 -An data.txt | xxd -p -r > data.rebuild
$ cmp --verbose data.txt data.rebuild 

プレーン形式以外の場合、1行のデータ数を -c で指定すれば、それ以降から行末までを切り捨てます

利用したテキストダンプの形式
000000 0a e5 90 8d e5 89 8d 0a 78 78 64 20 2d 20 31 36
000010 20 e9 80 b2 e3 83 80 e3 83 b3 e3 83 97 e3 82 92
000020 e4 bd 9c e6 88 90 e3 81 97 e3 81 9f e3 82 8a e3
$ od -tx1 -Ax data.txt | xxd -r > data.rebuild
$ cmp --verbose data.txt data.rebuild 

番外編 : uuencodeでテキスト化

uuencode 入力ファイル名 復元時のサンプルファイル名

-m : base64エンコード

$ uuencode data.txt rebuild_filename.txt
begin 644 rebuild_filename.txt
M"N60C>6)C0IX>&0@+2`Q-B#I@++C@X#C@[/C@Y?C@I+DO9SFB)#C@9?C@9_C
M@HKC@('EA8/C@:OFB+OC@9?C@9_C@HKC@((*YINXY;R/"GAX9"`M:%ME;'!=
M"GAX9"!;;W!T:6]N<UT@6VEN9FEL92!;;W5T9FEL95U="GAX9"`M<EME=F5R
M=%T@6V]P=&EO;G-=(%MI;F9I;&4@6V]U=&9I;&5=70KHJJSFF(X*XX.5XX*A
MXX*DXX.KXX*$YJB9YKJ6Y86EY8J;XX&+XX*)(#$V(.F`LN.#@..#L^.#E^."
MDN2]G.:(D..!E^.!ON.!F>.`@B`Q-B#I@++C@X#C@[/C@Y?C@8OC@HGEA8/C
M@:[C@Y#C@J3C@XKC@ZKC@:OFB+OC@9GC@9/C@:CC@H+C@:?C@8WC@;[C@9GC
M@((@=75E;F-O9&4H,2D@XX*$('5U9&5C;V1E*#$I(..!KN."B..!AN.!J^.`
M@>.#D.."I..#BN.#JN.#A^.#O.."O^."DN.`@>.#H>.#O..#J^.!J^BRO.."
MBN2[F..!D>6/K^B#O>.!JB!!4T-)22#EO:+EO(_C@:OEI(GFCYOC@:?C@8WC
M@9_C@HKC@('FJ)GFNI;EA[KEBIOC@:OEA[KEBIOC@9GC@HOC@9/C@:CC@H+C
M@:?C@8WC@;[C@9GC@((@XX&5XX*)XX&KXX"!XX.0XX*DXX.*XX.JXX.5XX*A
MXX*DXX.KXX&KXX.1XX.#XX.!XX*2Y;V3XX&FXX*+XX&HXX&$XX&&Y+V_XX&$
7YI:YXX*"XX&GXX&-XX&^XX&9XX""(`H`
`
end
$ uuencode -m data.txt "rebuild_filename.txt"
begin-base64 644 rebuild_filename.txt
CuWQjeWJjQp4eGQgLSAxNiDpgLLjg4Djg7Pjg5fjgpLkvZzmiJDjgZfjgZ/j
gorjgIHlhYPjgavmiLvjgZfjgZ/jgorjgIIK5pu45byPCnh4ZCAtaFtlbHBd
Cnh4ZCBbb3B0aW9uc10gW2luZmlsZSBbb3V0ZmlsZV1dCnh4ZCAtcltldmVy
dF0gW29wdGlvbnNdIFtpbmZpbGUgW291dGZpbGVdXQroqqzmmI4K44OV44Kh
44Kk44Or44KE5qiZ5rqW5YWl5Yqb44GL44KJIDE2IOmAsuODgOODs+ODl+OC
kuS9nOaIkOOBl+OBvuOBmeOAgiAxNiDpgLLjg4Djg7Pjg5fjgYvjgonlhYPj
ga7jg5DjgqTjg4rjg6rjgavmiLvjgZnjgZPjgajjgoLjgafjgY3jgb7jgZnj
gIIgdXVlbmNvZGUoMSkg44KEIHV1ZGVjb2RlKDEpIOOBruOCiOOBhuOBq+OA
geODkOOCpOODiuODquODh+ODvOOCv+OCkuOAgeODoeODvOODq+OBq+iyvOOC
iuS7mOOBkeWPr+iDveOBqiBBU0NJSSDlvaLlvI/jgavlpInmj5vjgafjgY3j
gZ/jgorjgIHmqJnmupblh7rlipvjgavlh7rlipvjgZnjgovjgZPjgajjgoLj
gafjgY3jgb7jgZnjgIIg44GV44KJ44Gr44CB44OQ44Kk44OK44Oq44OV44Kh
44Kk44Or44Gr44OR44OD44OB44KS5b2T44Gm44KL44Go44GE44GG5L2/44GE
5pa544KC44Gn44GN44G+44GZ44CCIAo=
====

このファイルを元に戻す時はuudecodeを使う。出力ファイル名は、uuendodeの実行時に指定した「復元時のサンプルファイル名」が使われる。

$ uudecode data.dump

番外編 : urlencodeでテキスト化

これは正しく復号できません…

-W : 入力ファイルがUTF-8
-w : 出力をUTF-8
-MQ : Quoted stream

$ nkf -WwMQ data.txt
 
=E5=90=8D=E5=89=8D
xxd=20=2D=2016=20=E9=80=B2=E3=83=80=E3=83=B3=E3=83=97=E3=82=92=E4=BD=9C=E6=
=88=90=E3=81=97=E3=81=9F=E3=82=8A=E3=80=81=E5=85=83=E3=81=AB=E6=88=BB=E3=
=81=97=E3=81=9F=E3=82=8A=E3=80=82
=E6=9B=B8=E5=BC=8F
xxd=20=2Dh=5Belp=5D

「=」を「%」に変換し、中途半端な改行を除去します…

$ nkf -WwMQ data.txt | tr = % | tr -d '\n'
%E5%90%8D%E5%89%8Dxxd%20%2D%2016%20%E9%80%B2%E3%83%80%E3%83%B3%E3%83%97%E3%82%92%E4%BD%9C%E6%%88%90%E3%81%97%E3%81%9F%E3%82%8A%E3%80%81%E5%85%83%E3%81%AB%E6%88%BB%E3%%81%97%E3%81%9F%E3%82%8A%E3%80%82%E6%9B%B8%E5%BC%8Fxxd%20%2Dh%5Belp%5Dxxd%20%5Boptions%5D%20%5Binfile%20%5Boutfile%5D%5Dxxd%20%2Dr%5Bevert%5D%20%5Boptions%5D%20%5Binfile%20%5Boutfile%5D%5D%E8%AA%AC%E6%98%8E%E3%83%95%E3%82%A1%E3%82%A4%

そして、復号してみると、必要な改行まで除去されています…

$ nkf -WwMQ data.txt | tr = % | tr -d '\n' | nkf -Ww --url-input
名前xxd - 16 進ダンプを作したり、元に戻たり。書式xxd -h[elp]xxd [options] [infile [outfile]]xxd -r[evert] [options] [infile [outfile]]説明ファイルや