Raccoon Tech Blog [株式会社ラクーン 技術戦略部ブログ]

株式会社ラクーン 技術戦略部より、tipsやノウハウなど技術的な話題を発信いたします。

社内勉強会

Zipファイルを紙とペンで解凍してみた

こんにちは。ほそかわです。

社内勉強会用に、埋めていくだけでzipファイルの解凍ができるプリントを作りました。

普段、zipファイルの解凍はコンピュータにやってもらっていますが、
この記事を読みながらご自身の手を使って紙とペンでやってみましょう。

アルゴリズムとデータ構造を生で感じるチャンスです。

準備

これから使うプリントをダウンロードして印刷しましょう。

「ZIPローカルファイルヘッダ」、
「ZIPセントラルディレクトリファイルヘッダ」、
「ZIPセントラルディレクトリ終端レコード」

記入してZIPの解凍を進めていくプリントです。

「ZIPファイルデータ」
この記事で解凍を行うzipファイルのバイナリデータです。
左側に書いてあるのは16進数で表されたバイナリデータです。主にこちらを使います。
16進数で書かれている行名と列名を足すと何byte目のアドレスにあるデータかが分かります。
右側に書いてあるのは文字列データが簡単に調べられるASCIIで表されたバイナリデータです。

「16進数表」
計算の手間を省くためのものです。

全て印刷して筆記用具も用意できたら準備はOKです。

今回用意したZIPファイルデータは、データ圧縮が行われていない特殊なzipファイルになってます。
圧縮を行わないzipファイルに意味なんてないと感じるかもしれませんが、圧縮に関する仕様は独立しているのでこの記事を読んだ後に別に勉強できます。

無圧縮のzipファイルはzipコマンドでも作れます。

zip -0 file.zip file.txt

プロトコルのバージョンによって違いがあるかもしれないのでこの記事ではこちらで用意したファイルを使います。

概要

Zipファイルの中にはどんなデータが入っているのか見てみましょう。

ファイル全体の概要を図にしました。

zip_overview_multi_file
Zipファイルはヘッダとファイルエントリ、終端レコードで構成されています。

ヘッダには2種類あります。

  • ZIPローカルファイルヘッダ
  • ZIPセントラルディレクトリファイルヘッダ

ZIPセントラルディレクトリファイルヘッダは、ZIPファイルの最後にあるZIPセントラルディレクトリという領域に入っています。そして、ZIPセントラルディレクトリの一番最後にアーカイブ全体についての情報が書いてある終端レコードが付いていてます。

ヘッダにはzipファイルに格納したファイルについてファイル名などの情報が書いてあり、ファイルエントリには格納したファイルの中身が入っています。

図のzipファイルにはA,Bの2つのファイルが格納されています。2種類のヘッダとファイルエントリがファイル数だけ繰り返されています。

ネタバレになってしまいますが繰り返しがあると手間が増えるばかりなので、今回使うzipファイルに格納されているファイルは一つです。

バイナリデータ

Zipファイルは普段扱っているテキストデータよりもコンピュータ向けなバイナリデータとして保存されています。

バイナリデータを扱う為に、16進数、2進数の変換方法とエンディアンについて知っておきましょう。

基礎的な知識なのでWikipediaをみてください。

2進法

16進数

エンディアン

エンディアンは様々なことが書いてありますが、zipファイルを扱うのにはリトルエンディアンとビックエンディアンのデータが読めるようになっていれば十分です。

リトルエンディアンでは1byteをかたまりとして並び順を逆にします。

AB CD EF 12

であれば

12 EF CD AB

となります。

例えば、16進数で1B58という数値をリトルエンディアンで表すと

58 1B

となります。

ビックエンディアンは並び順を変えないもので、

AB CD EF 12

であれば、そのまま

AB CD EF 12

となります。

ZIPセントラルディレクトリ終端レコード

これから紙とペンを使ってzipを解凍していきます。

まずは、アーカイブ全体の情報を得るために、セントラルディレクトリの終端レコードに記録してある情報を調べましょう。

使うプリントは、「ZIPセントラルディレクトリ終端レコード」です。

概要で説明したように、終端レコードはzipファイルの最後の領域にあります。

ZIPの仕様として終端レコードの頭には、

50 4B 05 06

というシグネチャをつけることになっています。

終端レコードはファイルの末尾にあるので末尾から開始地点を表すシグネチャを探すことで、終端レコードの領域を知ることができます。
zipファイルデータの末尾からシグネチャを探しましょう。

アドレス0x5Cに見つかりました。

そこからセントラルディレクトリヘッダの終端レコードが始まってます。
次のアドレスから順番にプリントに書き込んでいくと終端レコードの解凍を進められます。

四角い枠一つが1byteに対応してます。

入力欄解説
中には1byteのデータを書き込みます。

シグネチャは例としてリトルエンディアンで埋めてあります。

次の手順で全て埋めてみてください。

  1.  16進数で読み、数値データはリトルエンディアンで、(文字列)と書いてある文字列のデータはビックエンディアンで四角い枠の欄に記入する。

  2.  数値データは、16進数のデータを10進数に直して下線が引いてある欄に記入する。文字列のデータは1byteごとにASCII文字に変換してある右に表の同じ位置の文字を探して記入する。

(厳密には、文字列のデータもリトルエンディアンになっています。並び替えを行わないビックエンディアンとして扱えている理由は、1文字の1byte単位で保存が行われているからです。リトルエンディアンは1byteをかたまりとして並び替えるものなので、1byteのデータでは並び替えが行われず、リトルエンディアンになる並び替えが行われてないように見えています)

最初なので答えを載せます。

ZIPセントラルディレクトリ終端レコード_答え

全ての記入が終わったら細かく見て行きます。

セントラルディレクトリレコードの合計数

セントラルディレクトリレコードの数はファイルの数と同じになっています。
このzipファイルに含まれるファイルは一つだけだと分かります。

セントラルディレクトリの開始位置のオフセット、セントラルディレクトリのサイズについて

セントラルディレクトリの開始位置のオフセットからは、ファイルの先頭から見てどのアドレスでセントラルディレクトリが始まるのか、セントラルディレクトリのサイズからはどこまで続いているのかが分かります。
セントラルディレクトリは、先頭から39byte目のアドレス0x27で始まって53byte後のアドレス0x5Bで終わっているということがわかります。

Zipファイルコメントと長さについて

このzipファイルにはコメントがないため長さには0が入っています。
コメントは可変長のデータなのでここで長さを定義してそのバイト数だけコメントとして扱うという作りになってます。

その他の項目については、今では使われない機能が多いので割愛します。
興味があったら調べてみてください。

ZIPセントラルディレクトリファイルヘッダ

次は、セントラルディレクトリファイルヘッダです。
使うプリントは、「ZIPセントラルディレクトリファイルヘッダ」です。

終端レコードの情報から、セントラルディレクトリはアドレス0x27で始まっているとわかりました。
セントラルディレクトリファイルヘッダのシグネチャは、

50 4B 01 02

です。

探してみると、終端レコードで書いてあったようにアドレス0x27にあります。

終端レコードの時と同じようにシグネチャの次のバイトからプリントを埋めていきます。

zipでは、日付、時刻のデータがバイト単位で分けられてません。
2byteの領域に3つのデータが入っているので、
一度、2byteを繋げた2進数に変換してから区切り直して、10進数に変換します。

次の手順で行います。

  1. リトルエンディアンで2byte分を2進数に変換して一桁ずつ下線の上に書く
  2. 縦線で区切られているところで分けて2進数から10進数変換して、次の行に書き込む
  3. 秒は2倍、年は1980を足す

このやり方も初めてなので答えを載せておきます。

日時入力欄解説

これでファイルの最終変更日時がわかります。

これも全ての記入が終わったら細かく見ていきます。

圧縮メソッド
ファイルエントリがどのプロトコルで格納されたかが書いてあります。
今回は無圧縮なので0が入っていますが8のDeflateが一般的です。

Wikipedia - Deflate

ファイルの最終変更時刻、最終変更日付
格納したファイルの最終変更日時です。
年は1980の下駄を履かせるので1980年からが使えます。
そして、なんと、秒はビットが足らず2秒刻みで丸められているので2倍します。

zipで圧縮を行ったファイルは最終変更日時の秒が保障されないことをご存知だったでしょうか。いつも使っているものでも意外な発見があるものなんですね。

CRC-32
格納前のファイルエントリで計算したCRC-32が入っています。

圧縮サイズ
格納後のサイズです。ファイルエントリのサイズが書いてあります。

非圧縮サイズ
格納前のファイルサイズです。

ファイル名の長さ、ファイル名
Zipファイルコメントと同じようにまず長さが定義されていて、その長さ分のファイル名データがあります。

ローカルファイルヘッダの相対オフセット
ファイル一個につき、セントラルディレクトリファイルヘッダとローカルファイルヘッダが一つずつあります。

対応するローカルファイルヘッダのアドレスが書いてあります。
最初のファイルのローカルファイルヘッダのアドレスなので0が入っています。

数が多いので他は割愛します。
調べてみてください。

ZIPローカルファイルヘッダとファイルエントリ

ローカルファイルヘッダはZIPセントラルディレクトリファイルヘッダと同じやり方で埋めていけます。
ローカルファイルヘッダの次のアドレスからファイルサイズのバイト数分だけがファイルエントリと呼ばれるファイルの中身のデータになってます。

圧縮が行われている場合には、ヘッダから得た圧縮プロトコル情報をもとにファイルエントリのデコードを行います。今回は無圧縮なので飛ばせます。

ファイルエントリをこれまでヘッダから得た情報をもとにファイルとして保存すればこのファイルは解凍されます。

今回は、

  • ファイルの最終変更日は「2016年1月26日 13時27分36秒」
  • ファイル名は「raccoon」
  • ファイルの中身は「CA FE」

というファイルを作り、ファイルエントリをそのまま中に書き込めばこのzipファイルの解凍は成功です。

「CA FE」とは16進数で使われるA~Fまでの文字という制約で考えた単語「Cafe」です。

最後に

お疲れ様でした!

Zipファイルが身近に感じられるようになったのではないでしょうか。

この記事は最短ルートでzipファイル概要を理解し解凍を体験できることを目標に書いたので多くの仕様を省略しています。
次のステップとして、圧縮アルゴリズムを勉強すると圧縮が行われている普通のzipファイルも解凍できるようになります。他にもパスワード付きや分割など多くの仕様があります。そして、反対のことを行えば圧縮もできます。

ZIPファイルフォーマットは様々なところで使われています。ZIPの知識を生かすことで仕事の幅が広がるかもしれません。このプリントを使って勉強会を開催するのも面白いでしょう。
これからの活躍につながるといいですね。

参考

wikipedia - ZIP

PK-Ware - APPNOTE

技術戦略部有志イベント『エンジニアの宴』を開催しました

kanpai


こんにちはなべです。
技術戦略部有志のイベント『エンジニアの宴』をレポートします。

『エンジニアの宴』というのは、全社的なイベントではできない企画で、エンジニアらしく楽しんでしまおうという、エンジニアのための、エンジニアによる、『エンジニアの宴』です。
 
コンテンツはLT大会とFightCode大会です。

それでは早速ご紹介します。 



第1部 LT大会

   
25 27-IMG_3701 22-IMG_3698

ネタは、最近業務で作ったJSライブラリ、ソフトウェア業界の偉人(変人?)、WindowsAPI Hookから、
エンジニアとはあまり関係ない、最近流行の陣取りゲーム、
最後は、エンジニアとは全く関係ないお掃除に使う洗剤の話まで多種多様。
日頃のLT大会とはまた違ってゆるいネタで盛り上がりました!
 


第2部 FightCode大会

56 32 54

FightCodeは、JavaScriptでロボットの動きを実装して戦うゲームです。 
今回の参加者は10名。総当りで戦いました。 
普段JavaScriptを使っている人もそうでない人も、それぞれの叡智を結集して戦いに臨みました。
強いロボットが順当に勝つときもあれば、それだけではなく運の要素も絡んで金星などもあり盛り上がりました!


51


最後は、エンジニアらしく、それぞれのコード解説。
”勝つ!”という同じ目的で作ったコードですが、それぞれ考えた作戦もさまざまなので、コードもさまざまです。 
作戦に性格が出ていたり、強いコードは必ずしも行数が多いわけではなかったりして、ツッコミを入れたり感心したりしながら、それを肴に最後の〆。

日頃の研修や勉強会とはまた違ったゆるく楽しい宴でした。
 

Fabric + Serverspec 社内勉強会

こんにちは。主にCORECの開発に携わっている、技術戦略部のおおはらです。

同部の松尾が主催した「Fabric + Serverspec 社内勉強会」に参加しました。

勉強会のゴールはFabricを使ってサーバに設定をし、正しく設定されたことをServerspecで確認する、ということです。

今回のハンズオン環境として、FabricとServerspecがインストールされたUbuntuのVMイメージが事前に配布されました。それをVMWare PlayerまたはVirtual Boxを使って各自のノートPCにハンズオン環境を構築しています。

最初に、松尾からハンズオンをスムーズに進めるためにUbuntuの便利な使い方(ワークスペース、tmux)の説明がありました。そして、勉強用のサーバをAWS上に各自作成しました。

IMG_20150313_145328


次にFabricの基本的な説明がありました。
FabricはPython製のデプロイツールで、サーバでsshが動いていればOK(サーバにpython不要)、既存のシェルスクリプトとFabricのメソッドでタスクを簡単に書ける、といった特徴を持ちます。
具体的なタスクの書き方、fabコマンドによるタスクの実行の仕方の解説の後、実習としてnginxのインストールやスタート、crontabの更新といったタスクを作成、実行しました。

最後にServerspecの解説です。
ServerspecはRuby製のサーバ自動テストツールで、サーバでsshが動いていればOK、RSpec形式でテストコードが書ける、といった特徴があります。
勉強会資料を参考に、Fabricでインストールしたnginxが動作していることを、Serverspecでテストを書き、実行して確認しました。

デプロイツールには大規模なシステムでの実績があるChefやAnsibleといった有名なものもありますが、別の選択肢としてシンプルにタスクが書けるFabricが弊社では上手く使えそうな気がします。

私が携わっているCORECではサーバ設定の一部をwikiで管理したり手動設定している部分があります。まずは、設定をファイルとしてgitで管理し、Fabricで設定することから始めていこうと思いました。

Vagrantパッケージ作成勉強会

開発の下田です。
社内勉強会に参加しました。今回のテーマは仮想環境構築ツールの「Vagrant」です。
Vagrantはコマンド一発で仮想環境を構築したり、ある時点のスナップショットからパッケージにしたりといった、仮想環境の管理ができます。

20141226_150439

概要

仮想環境を作成できるパッケージを作成することがテーマです。
弊社のBtoB締め支払い決済「Paid」のWebサーバの仮想化イメージ(VMware vmdk)から、Vagrantのパッケージboxを作成します。

単にboxを作成するならvagrant packageコマンドを実行するだけですが、既にある環境からboxを作成するには、ノウハウが必要になります。
今回の勉強会では、ハンズオン形式で実際に構築しながら勉強しました。

手順

1.VirtualBox等の仮想環境マネージャーで仮想マシンを作成

2.vmdkイメージを仮想マシンに追加

3.仮想マシンを起動し、不要なサービスを停止

サービス一覧(chkconfig --list | grep :on)を目視確認し、postfixなどのメール、監視ツールなど、外部に影響があるサービスは確実に停止します。

4.NFSを使用している場合は、マウント解除

5.vagrantユーザの作成

vagrantではゲストOSにSSHで接続するコマンドが用意されています。このとき、ユーザ:vagrant、パスワード:vagrantで接続にいきます。
vagrantユーザを作成しておき、sudoersに追加しておくと便利です。

6.ネットワーク設定

7.Vagrantのパッケージ化


ポイント

1.ホストマシンのネットワークを切断する。

本番イメージを使用するときは、起動スクリプトやcronでメール配信など、外部へ影響が発生するおそれがあります。必ずネットワークから隔離した状態で構築しましょう。

2.元の環境のネットワークを再現する。

元の環境とできるだけ似たネットワーク構成を再現できると、環境の再現性が高くなります。うまくできるかどうかが、アプリケーションの動作などに影響するため重要なポイントです。
VirtualBoxを使用している場合はホストオンリーネットワークをセグメントごとに作成します。

まとめ

Vagrantのパッケージ化はコマンド一発で終わりなので、非常に簡単です。
不完全な状態でもVagrantのパッケージ化を行っておけば、Vagrantでパッケージ化した時点までロールバックできるので、トライアンドエラーが簡単にできました。
開発環境をパッケージ化してから、1日がかりだった環境構築が1時間程度(ほぼ待ち時間で実作業は一瞬)でできるようになりました。

AWS社内勉強会

AWSの社内勉強会を技術戦略部の松尾を講師として開催しました。

AWSは、2014年3月にサービスインしたCOREC(コレック)で使われ始めてから
社内で勢いを増してきています。


今回の勉強会は

1. VPC (Virtual Private Cloud)
2. EC2 (Elastic Compute Cloud)
3. RDS (Relational Database Service)
4. Route 53
5. SES (Simple Email Service)
6. S3 (Simple Storage Service)
7. IAM (Identity and Access Management)
8. SQS (Simple Queue Service)

の概要から説明していただき、
各自AWS マネジメントコンソールからEC2インスタンスの起動と終了を操作したり、
AWS SDK for Rubyを使ってS3へファイルをアップロードしたりしました。

IMG_0547

次回の社内勉強会は・・・まだ未定です。
記事検索