rubyのIPAddrクラスを使えばIPアドレスがCIDR範囲に含まれるかもチェックできる
rubyにはIP アドレスを扱うのためのIPAddrクラスがあります。
このIPAddrクラスを使えば、IPアドレスがCIDR範囲に含まれるかもチェックできます。
irb(main):001:0> require 'ipaddr' => true irb(main):002:0> cidr_sample = IPAddr.new("192.0.2.0/24") => #<IPAddr: IPv4:192.0.2.0/255.255.255.0> irb(main):003:0> cidr_sample.include? "192.0.2.1" => true irb(main):004:0> cidr_sample.include? "192.0.2.255" => true irb(main):005:0> cidr_sample.include? "192.1.2.0" => false
便利!
参考
MTUについて
MTUとは
MTUは最大転送単位(Maximum Transmission Unit)
MTUはデータリンク層(L2)の性質となる。
データリンク層での最大のフレーム長(データリンク層のパケットを表すときにはフレームが使われる。)
MTUはデータリンク層での性質なので、IP層(L3)のヘッダーまでを含んでいる。
IPはデータリンクの上位層なので、MTUを隠蔽する役割を持つ。
そこで、データリンクを司るルーターなどはMTUに応じてIPデータグラムを分割する(IP fragmentation フラグメンテーション)。 (データグラムはIPなどのネットワーク層以上でのパケット単位のデータ構造を持つプロトコルで利用される表現)
IPヘッダーには分割されたパケットを管理するためのフラグがある。
分割されたIPデータグラムを元のIPデータグラムに戻す再構築の処理は終点の宛先ホストでのみ行われる。
TCPの場合
トランスポート層(L4)でTCPを使う場合、一度にTCPで含められるアプリケーションデータのサイズは、MTUからIPヘッダー(20バイト)とTCPヘッダー(20バイトとオプションがあると60バイトまで増える)を除いたバイト数となる。
このサイズをMSS(Mazimum Segment Size 最大セグメント長)と呼ぶ。(セグメントはTCPに含まれるデータの表すときに使う)
TCPでは3ウェイ・ハンドシェイクのときに、コネクション確立要求を送るときに、送信側、受信側ともに自身のMSSを通知し、小さいMSSを採用する。
MSSに沿って、データを区切って送信されるため、IPでの分割は行わず、TCP側で再構築をする。
再送処理はMSS単位で行われる。
手元でWireSharkで確認してみた例
MSSを相互に通知している様子
MSSによって分割されたデータを再構築している
参考文献
https://www.cloudflare.com/ja-jp/learning/network-layer/what-is-mtu/
MySQLにおける外部キー作成時の自動インデックス生成
MySQLの外部キー制約において、外部キーと参照キーにはインデックスが必要です。
下記はMySQL 8.0のドキュメントですが、5.7でも同じような内容となっています。
参照元のテーブルには、外部キーのカラムが同じ順序で最初のカラムとしてならぶインデックスが必要です。 もし該当するindexがなければ、MySQLは自動でインデックスを作成します。 この自動で作られたインデックスは後で追加したインデックスが外部キーのインデックス要件を満たす場合、暗黙的に削除されることがあります。
これを実際に試してみようと思います
確認したMySQLのバージョンは 8.0.29 です。
まずテーブルを作ってみます
mysql> CREATE TABLE `users` ( -> `id` int NOT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE `user_foo` ( -> `id` int NOT NULL AUTO_INCREMENT, -> `user_id` int NOT NULL, -> `foo` int NOT NULL, -> PRIMARY KEY (`id`), -> CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec)
これでテーブル定義を見てみます。
mysql> SHOW CREATE TABLE user_foo; +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | user_foo | CREATE TABLE `user_foo` ( `id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `foo` int NOT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), <----- CREATE文にないindexが追加されている CONSTRAINT `user_foo_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
CREATE文にないインデックスが自動で作られます。
外部キーのcolumnが同じ順序で最初のカラムとしてならぶインデックスが必要です。
これを確認してみましょう。
外部キーを含む複数カラムに対してセカンダリインデックスを追加してみます。
mysql> CREATE TABLE `users` ( -> `id` int NOT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE `user_foo` ( -> `id` int NOT NULL AUTO_INCREMENT, -> `user_id` int NOT NULL, -> `foo` int NOT NULL, -> PRIMARY KEY (`id`), -> KEY (`user_id`, `foo`), -> CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> SHOW CREATE TABLE user_foo; +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | user_foo | CREATE TABLE `user_foo` ( `id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `foo` int NOT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`,`foo`), CONSTRAINT `user_foo_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
今度は自動でのインデックスが追加されていません。
user_idとfooのセカンダリインデックスで外部キー制約のインデックスの要件を満たしたためですね。
では今度はuser_idとfooを逆にしてみます。
mysql> CREATE TABLE `users` ( -> `id` int NOT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE `user_foo` ( -> `id` int NOT NULL AUTO_INCREMENT, -> `user_id` int NOT NULL, -> `foo` int NOT NULL, -> PRIMARY KEY (`id`), -> KEY (`foo`, `user_id`), -> CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> SHOW CREATE TABLE user_foo; +----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | user_foo | CREATE TABLE `user_foo` ( `id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `foo` int NOT NULL, PRIMARY KEY (`id`), KEY `foo` (`foo`,`user_id`), KEY `user_id` (`user_id`), CONSTRAINT `user_foo_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
今度は 外部キーのcolumnが同じ順序で最初のカラムとしてならぶインデックスにならなかったため、user_id単独のセカンダリインデックスが自動で追加されました。
今度は外部キー制約を満たすために追加したインデックスが不要になるインデックスが追加されたときの挙動を見てみます。
mysql> CREATE TABLE `users` ( -> `id` int NOT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE `user_foo` ( -> `id` int NOT NULL AUTO_INCREMENT, -> `user_id` int NOT NULL, -> `foo` int NOT NULL, -> PRIMARY KEY (`id`), -> CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Query OK, 0 rows affected (0.01 sec) mysql> SHOW CREATE TABLE user_foo; +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | user_foo | CREATE TABLE `user_foo` ( `id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `foo` int NOT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), <---- 自動で追加されたインデックス CONSTRAINT `user_foo_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
自動でインデックスが追加されています。
では、新たにインデックスを追加してみます。
mysql> ALTER TABLE user_foo ADD INDEX (`user_id`,`foo`); Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> SHOW CREATE TABLE user_foo; +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | user_foo | CREATE TABLE `user_foo` ( `id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `foo` int NOT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`,`foo`), CONSTRAINT `user_foo_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
user_id単体ではられていたインデックスが削除され、ALTERによって追加されたインデックスのみが残りました。
ではこのインデックスを削除してみるとどうなでしょう。
mysql> ALTER TABLE user_foo DROP INDEX `user_id`; ERROR 1553 (HY000): Cannot drop index 'user_id': needed in a foreign key constraint
この場合は、自動でインデックスが追加されるわけではなく、外部キー制約に必要なるということでエラーになります。
ActiveRecordのcallbackの実装を調べたときのメモ
Railsのcallbackの実体
callbackはActiveSupport::Callbacksを使って定義されます。
ActiveRecordのcallback
ActiveRecord::Callbacksに定義があります。
ここでcreateなどが定義されます。
define_model_callbacksは下記で実装されています。
例 : after_create hookの呼び出され方
ActiveRecord::Baseを継承したUserクラスを考えます。
Railsのバージョンは6.1.4.6を使っています。
Userクラスにはcreateというクラスメソッドがあり、recordを登録できます。
実体は、
irb(main):002:0> User.method(:create) => #<Method: User(id: integer, .....).create(attributes=..., &block) /path/to/..../gems/activerecord-6.1.4.6/lib/active_record/persistence.rb:33>
なので、下記です。
hookがどのように呼び出されるかがわかりにくいので、下記でbreak pointを仕込んでおきます。
で、after_commit のcallbackをなにかしら設定しておいて、User.createを実行してみます
irb(main):001:0> User.create(....) [1] pry(User)> TRANSACTION (0.2ms) BEGIN From: /path/to/..../gems/activerecord-6.1.4.6/lib/active_record/callbacks.rb:461 ActiveRecord::Callbacks#_create_record: 460: def _create_record => 461: binding.pry 462: _run_create_callbacks { super } 463: end
とまりましたね。 ここでcallerを一部抜粋すると
"/activerecord-6.1.4.6/lib/active_record/callbacks.rb:461:in `_create_record'", "/activerecord-6.1.4.6/lib/active_record/timestamp.rb:108:in `_create_record'", "/activerecord-6.1.4.6/lib/active_record/persistence.rb:903:in `create_or_update'", "/activerecord-6.1.4.6/lib/active_record/callbacks.rb:457:in `block in create_or_update'", "/activerecord-6.1.4.6/lib/active_record/persistence.rb:477:in `save'"
saveから callbacksの _create_record が呼ばれて、ここでcallbackが発動することとなります。
after_createはcommit前に発動するので、このcallback内で新しくinsertした内容を別のトランザクションからは取得できないので要注意です。
Railsのrspecのrequest specについて
上記の記事にあるように、Rails 5以降ではrails-controller-testing gemをアプリケーションに追加することは推奨されておらず、RSpecコアチームはrequest specsを書くことを推奨しています。
その理由として、request specでは、単一のcontroller actionをテストしつつ、さらにcontroller specとは異なり、router、middleware、rackのrequestとresponseが含まれることになります。
これにより、書いているテストがより実際のリクエストに近くなり、controller testにありがちな問題を回避することができます。
Rails 5ではRails 4のrequest specやcontroller specに比べてかなりの高速化も行われています。
このように、controller specはよりrequest specを書くことがRails 5以降のデファクトとなっています。
GitHub - rspec/rspec-rails: RSpec for Rails 5+
request spec - Request specs - RSpec Rails - RSpec - Relish
request specの使用
rspec-railsを使った場合、specのtypeをtop-levelのdescribeで指定します。
RSpec.describe User, type: :request do
requestを指定することで、ActionDispatch::IntegrationTestに相当することになります。
この中でHTTP requestをシュミレートする get
post
patch
put
delete
head
メソッドを使うことになります。
controller specでも同じようなメソッドを使うことになりますが、呼び出されたメソッドが実行するものが違います。
実装は下記になります。
この中で、 Rack::Test::Session
が使われており、Rails appではなく、Rack appとしてリクエストを処理するようになっています。
request specはRackのレイヤーまでを網羅したテストとなっています。
ちょっとハマった点
rack appに対するリクエストを組み立てテストを行うのですが、Rack::Test:Session#requestの実装が少し色々やりすぎててハマりました
このなかで、specで定義したparamsをURL-encoded form dataにエンコードを自動的に行なっているので、テストもとでencodeすると二重でencodeされることになります。
こういった処理をどこまでやるかの判断は難しいですが、自動的に行われることは意識しておいていいかなと思います。
線形合同法(Linear congruential method)のスペクトル検定による可視化
ここでのA(乗数) C(増分) M(法)は定数で、AとCはMより小さい数を選ぶ。
このA C Mの選び方によって周期性は変わる。
どういう選び方すればをいいかは下記本を参照ください。
線形合同法で生成された数列がどれくらい乱雑かを判定する方法の一つにスペクトル検定がある。
今回は三次元でこれをグラフにしてみた。
Rubyのrandはメルセンヌ・ツイスタなので、それと線形合同法で生成した乱数の分布を比べてみる。
適当なスクリプトを書いて可視化した結果が下記の図となる。
可視化にはGR.rbを利用している。
- メルセンヌ・ツイスタ
- 線形合同法(A(乗数)を137、C(増分)を187、M(法)を256にしているので規則性がわざと出やすくしている)
こう見ても今回のパラメータの線形合同法の結果は乱雑さがない感じがする。
参考資料
http://www.math.sci.hiroshima-u.ac.jp/m-mat/TEACH/ichimura-sho-koen.pdf
バイナリファイルを見る方法
白く塗りつぶしたpngファイルの例でやってみる。
% convert -size 128x128 xc:white white.png
vimを使う場合
vim -b white.png
でバイナリモードでvimで開いた後に下記コマンドでバイナリダンプします。
:%!xxd
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 00000010: 0000 0080 0000 0080 0100 0000 00eb 455c ..............E\ 00000020: 6600 0000 0467 414d 4100 00b1 8f0b fc61 f....gAMA......a 00000030: 0500 0000 2063 4852 4d00 007a 2600 0080 .... cHRM..z&... 00000040: 8400 00fa 0000 0080 e800 0075 3000 00ea ...........u0... 00000050: 6000 003a 9800 0017 709c ba51 3c00 0000 `..:....p..Q<... 00000060: 0262 4b47 4400 01dd 8a13 a400 0000 0774 .bKGD..........t 00000070: 494d 4507 e602 170e 1622 78a1 b740 0000 IME......"x..@.. 00000080: 001f 4944 4154 48c7 63f8 8f06 1846 0546 ..IDATH.c....F.F 00000090: 0546 0546 0546 0546 0546 0546 0568 2b00 .F.F.F.F.F.F.h+. 000000a0: 0004 a0f8 6a22 6527 5400 0000 2574 4558 ....j"e'T...%tEX 000000b0: 7464 6174 653a 6372 6561 7465 0032 3032 tdate:create.202 000000c0: 322d 3032 2d32 3354 3134 3a32 323a 3334 2-02-23T14:22:34 000000d0: 2b30 303a 3030 d063 4c5a 0000 0025 7445 +00:00.cLZ...%tE 000000e0: 5874 6461 7465 3a6d 6f64 6966 7900 3230 Xtdate:modify.20 000000f0: 3232 2d30 322d 3233 5431 343a 3232 3a33 22-02-23T14:22:3 00000100: 342b 3030 3a30 30a1 3ef4 e600 0000 0049 4+00:00.>......I 00000110: 454e 44ae 4260 82 END.B`.
ちなみにバイナリモードでファイルを開かないとバイナリ表示がおかしくなるので注意 下記はバイナリモードで開かなかった場合のバイナリダンプ
00000000: 3f50 4e47 0d0a 1a0a 0000 000d 4948 4452 ?PNG........IHDR 00000010: 0000 003f 0000 003f 0100 0000 003f 455c ...?...?.....?E\ 00000020: 6600 0000 0467 414d 4100 003f 3f0b 3f61 f....gAMA..??.?a 00000030: 0500 0000 2063 4852 4d00 007a 2600 003f .... cHRM..z&..? 00000040: 3f00 003f 0000 003f 3f00 0075 3000 003f ?..?...??..u0..? 00000050: 6000 003a 3f00 0017 703f 3f51 3c00 0000 `..:?...p??Q<... 00000060: 0262 4b47 4400 01dd 8a13 3f00 0000 0774 .bKGD.....?....t 00000070: 494d 4507 3f02 170e 1622 783f 3f40 0000 IME.?...."x??@.. 00000080: 001f 4944 4154 483f 633f 3f06 1846 0546 ..IDATH?c??..F.F 00000090: 0546 0546 0546 0546 0546 0546 0568 2b00 .F.F.F.F.F.F.h+. 000000a0: 0004 3f3f 6a22 6527 5400 0000 2574 4558 ..??j"e'T...%tEX 000000b0: 7464 6174 653a 6372 6561 7465 0032 3032 tdate:create.202 000000c0: 322d 3032 2d32 3354 3134 3a32 323a 3334 2-02-23T14:22:34 000000d0: 2b30 303a 3030 3f63 4c5a 0000 0025 7445 +00:00?cLZ...%tE 000000e0: 5874 6461 7465 3a6d 6f64 6966 7900 3230 Xtdate:modify.20 000000f0: 3232 2d30 322d 3233 5431 343a 3232 3a33 22-02-23T14:22:3 00000100: 342b 3030 3a30 303f 3e3f 3f00 0000 0049 4+00:00?>??....I 00000110: 454e 443f 4260 3f0a END?B`?.
hexdumpコマンドを使う場合
受け取ったデータを8進数や16進数でダンプする。(デフォルト16進数)
hexdumpはオプションなしでは、2バイト単位で処理し、リトルエンディアン(最下位のバイトから順番に表示)で表示します。
-C
オプションをつけることで1バイトずつ処理をする。
なので、基本 -C
オプションを付けて使う。
% hexdump -C white.png 00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR| 00000010 00 00 00 80 00 00 00 80 01 00 00 00 00 eb 45 5c |..............E\| 00000020 66 00 00 00 04 67 41 4d 41 00 00 b1 8f 0b fc 61 |f....gAMA......a| 00000030 05 00 00 00 20 63 48 52 4d 00 00 7a 26 00 00 80 |.... cHRM..z&...| 00000040 84 00 00 fa 00 00 00 80 e8 00 00 75 30 00 00 ea |...........u0...| 00000050 60 00 00 3a 98 00 00 17 70 9c ba 51 3c 00 00 00 |`..:....p..Q<...| 00000060 02 62 4b 47 44 00 01 dd 8a 13 a4 00 00 00 07 74 |.bKGD..........t| 00000070 49 4d 45 07 e6 02 17 0e 16 22 78 a1 b7 40 00 00 |IME......"x..@..| 00000080 00 1f 49 44 41 54 48 c7 63 f8 8f 06 18 46 05 46 |..IDATH.c....F.F| 00000090 05 46 05 46 05 46 05 46 05 46 05 46 05 68 2b 00 |.F.F.F.F.F.F.h+.| 000000a0 00 04 a0 f8 6a 22 65 27 54 00 00 00 25 74 45 58 |....j"e'T...%tEX| 000000b0 74 64 61 74 65 3a 63 72 65 61 74 65 00 32 30 32 |tdate:create.202| 000000c0 32 2d 30 32 2d 32 33 54 31 34 3a 32 32 3a 33 34 |2-02-23T14:22:34| 000000d0 2b 30 30 3a 30 30 d0 63 4c 5a 00 00 00 25 74 45 |+00:00.cLZ...%tE| 000000e0 58 74 64 61 74 65 3a 6d 6f 64 69 66 79 00 32 30 |Xtdate:modify.20| 000000f0 32 32 2d 30 32 2d 32 33 54 31 34 3a 32 32 3a 33 |22-02-23T14:22:3| 00000100 34 2b 30 30 3a 30 30 a1 3e f4 e6 00 00 00 00 49 |4+00:00.>......I| 00000110 45 4e 44 ae 42 60 82 |END.B`.| 00000117
xxdコマンドを使う場合
ファイルを16進数でダンプする。 復元もできるのがポイント。
% xxd white.png 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 00000010: 0000 0080 0000 0080 0100 0000 00eb 455c ..............E\ 00000020: 6600 0000 0467 414d 4100 00b1 8f0b fc61 f....gAMA......a 00000030: 0500 0000 2063 4852 4d00 007a 2600 0080 .... cHRM..z&... 00000040: 8400 00fa 0000 0080 e800 0075 3000 00ea ...........u0... 00000050: 6000 003a 9800 0017 709c ba51 3c00 0000 `..:....p..Q<... 00000060: 0262 4b47 4400 01dd 8a13 a400 0000 0774 .bKGD..........t 00000070: 494d 4507 e602 170e 1622 78a1 b740 0000 IME......"x..@.. 00000080: 001f 4944 4154 48c7 63f8 8f06 1846 0546 ..IDATH.c....F.F 00000090: 0546 0546 0546 0546 0546 0546 0568 2b00 .F.F.F.F.F.F.h+. 000000a0: 0004 a0f8 6a22 6527 5400 0000 2574 4558 ....j"e'T...%tEX 000000b0: 7464 6174 653a 6372 6561 7465 0032 3032 tdate:create.202 000000c0: 322d 3032 2d32 3354 3134 3a32 323a 3334 2-02-23T14:22:34 000000d0: 2b30 303a 3030 d063 4c5a 0000 0025 7445 +00:00.cLZ...%tE 000000e0: 5874 6461 7465 3a6d 6f64 6966 7900 3230 Xtdate:modify.20 000000f0: 3232 2d30 322d 3233 5431 343a 3232 3a33 22-02-23T14:22:3 00000100: 342b 3030 3a30 30a1 3ef4 e600 0000 0049 4+00:00.>......I 00000110: 454e 44ae 4260 82 END.B`.
xxd -r でdumpしたファイルから復元して新しいデータとして保存する