2013年10月14日月曜日

P2P探訪 Raider 最初のメッセージ

TorrentクローンをJava で作成しています。
そろそろ、Applet上で動作するデモができそうです。 試してみて解ったことが結構ありました。
そこで、学習したしことを、epub形式でまとめています。http://p.booklog.jp/users/kyorohiro


やる気スイッチが入らないので、書きかけの物をさらします。



-----------------

最初のメッセージ

 TorrentクライアントはHandShakeが完了すると、次に 自分の持っているデータの相手に通知します。またデータを配信する場合、相手にデータを配信する意図がある事を伝えます。
 

どのデータを持っているかをBitfieldとして渡す。

 最初に送信するメッセージはBitfieldです。自分がどのようなデータを持っているかを相手に知らせます。 

データを分割して管理している 

  Torrent方式ではデータを分割して管理しています。 分割する単位はTorrentファイルに記載されておりTorrentネットワーク内で分割単位を共有しています。実際に分割したデータをPieceと読んでいます。通常、Pieceは「16KB」「32KB」「64KB」「128KB」「256KB」といった単位で分割されます。

 分割したデータには、1番から昇順に番号が降られます。例えば、160KBのデータを16KBで分割する場合、「0-16KB」までのデータを1番、「16-32KB」までのデータを2番、...「152KB-160KB」までのデータを10番と行った感じで番号が降られます。
 

データをBitfieldで渡す

 データを持っている場合は1。持っていない場合は0が設定します。例えば、160KBのデータを16KBで分割する場合、例えば、1番目のデータを持っている場合、「0x80 0x00」のようなバイトデータになります。 1番目と10番目のデータを持っている場合は、「0x80, 0x40」とったバイトデータになります。
 
以下のようなフォーマットで送信されます。
  • 0-4バイト1+Bitfieldのサイズ
  • 4-5バイト5
  • 5- Bitfieldの生データ(byte単位)
 具体的に、 メッセージとして「0x00, 0x00, 0x00, 0x03, 0x05, 0x80, 0x40」のようなバイトデータを送信します。「0x00, 0x00, 0x00, 0x03」がメッセージのサイズ、「0x05」が識別子、「0x80, 0x40」が持っているPieceの情報です。
 

相手にデータを配信する意思があることを伝える

 データを配信する意思があることを相手に伝えます。Torrent方式ではデータを配信する意図を示した端末のみデータを配信してくれます。
  

データ配信する意図を示す(unchoke)

 具体的には、unchokeメッセージを送信します。このメッセージを受け取ると相手のクライアントからrequestメッセージが呼ばれデータの配信が開始されます。
 unchokeメッゼージは以下のようなフォーマットです。
  • 0-4バイト目1
  • 4-5バイト目1
 
 具体的には、「0x00, 0x00, 0x00, 0x01, 0x01」のようなバイトデータを送信します。
 


P2P探訪 Raider ハンドシェークしてみる

TorrentクローンをJava で作成しています。
そろそろ、Applet上で動作するデモができそうです。 試してみて解ったことが結構ありました。
そこで、学習したしことを、epub形式でまとめています。http://p.booklog.jp/users/kyorohiro


やる気スイッチが入らないので、書きかけの物をさらします。



-----------------

ハンドシェークしてみる

  Trackerから、ピアの情報を所得できるようになりました。 これで、データを配信してるTorrentクライアントと接続できるようになりました。  本章では、他のTorrentクライアントへデータの転送許可を取る機能を実現します。
  

TorrentクライアントはTCPサーバー/クライアント

 TorrentクライアントはP2Pアプリです。Torrentクライアントはサーバーとクライアントの両方の機能を持っています。他のTorrentクライアントから接続を受け入れ、データを配信する」というサーバー的な機能。そして、「他のTorrentクライアントへ接続しデータを転送してもらう」というクライアント的な機能です。
 
 しかし、P2Pといっても、特別な方法で通信はしているわけではありません。汎用的な方法が利用されています。Torrentクライアントでは通信にTCP/IPを使用しています。TCP/IPはHttp通信で使用されています。これは、ブラウザーから「youtube」や「Google」にアクセスする時に使用する通信方法と同じ仕組みです。 

Handshakeする

 実際に、Torrentサーバーへ接続してみましょう。Torrent方式では、最初の接続/通信でデータ転送の許可をとります。この時、転送して欲しいデータについての情報をサーバーへ渡します。サーバーはそのデータが持っていれば、基本的に接続を受け入れます。
  

Socketで接続

まずは、Trackerから取得したアドレスへTCP/IPのソケットを生成して接続します。
 
SocketChannel socketChannel = SocketChannel.open();;
socketChannel.connect(new InetSocketAddress(hostname, port));
 
 
この時に生成したコネクションは、データ転送が完了するまで使用し続けます。Http1.0などを利用している古いサーバーなどでは、データを転送するたびに、コネクションを張ります。しかし、Torrentでは一度生成したコネクションはデータ転送が完了するまで確保し続けます。
 
 

データ転送の許可をとる

 接続を開始する前にお互いの情報を交換します。このメッセージの交換をHashshakeと呼びます。
  • 0-1バイト19
  • 1-20バイト"BitTorrent protocol"
  • 20-28バイト {0 0 0 0 0 0 0 0} のバイト配列
  • 28-48バイトInfoHash
  • 48-68バイトPeerId
 を送信します。するとサーバーから、
  • 0-1バイト19
  • 1-20バイト"BitTorrent protocol"
  • 20-28バイト {0 0 0 0 0 0 0 0} のバイト配列
  • 28-48バイトInfoHash
  • 48-68バイトPeerId
とメッセージが返されます。
 

@"19","BitTorrent protocol"

 先頭は識別子が入ります。19は識別子の文字数です。 その後、識別子である「BitTorrent protocol」が続きます。

@{0 0 0 0 0 0 0 0}

 拡張機能を利用するかのフラグです。 例えばDHTをサポートしている場合は0x01がセットされます。


@InfoHash

 どのデータをダウンロードしたいのかを表すHashです。TorrentクライアントのInfo辞書のSHA1です。


@PeerId

 Trackerへ渡したPeerIdを渡してください。

2013年7月17日水曜日

P2P探訪 Raider トラッカーにアクセスしてみる

TorrentクローンをJava で作成しています。
そろそろ、Applet上で動作するデモができそうです。 試してみて解ったことが結構ありました。
そこで、学習したしことを、epub形式でまとめています。http://p.booklog.jp/users/kyorohiro


やる気スイッチが入らないので、書きかけの物をさらします。



-----------------

トラッカーにアクセスしてみる

TorrentからTrackerサーバーのアドレスを取得するできました。これでTrackerへ接続する準備ができました。さっそくTrackerにアクセスしてみましょう。

TrackerはHttpサーバーです。 「ピアID」と「Info辞書のHash」と「ポート番号」を渡すと、ピアの一覧を返してくれます。 Httpサーバーなので、「ピアID」と「Info辞書のHash」を持つURLさえ生成すれば、ブラウザからもアクセスできます。
まずは、 URLを生成して、Trackerからピアのリストを取得してみましょう。

ピアIDを準備する

Trackerへアクセスする際に、peer_idが要求されます。 peer_idは20バイトのユニーク値を持つバイト配列です。
このidは、クライアントを識別するのも活用できます。 詳しくは、http://www.bittorrent.org/beps/bep_0020.html を参照してみてください。 

例えば、以下のような感じでかける。
public static String createPeerId() {
byte[] peerId = new byte[20]; 
Random random = new Random(System.currentTimeMillis());
random.nextBytes(peerId);
System.arraycopy("-KY-".getBytes(), 0, peerId, 0, 8);
PercentEncoder encoder = new PercentEncoder();
return encoder.encode(peerId);
}
※ せっかく20バイトもデータがあのに、System.currentTimeMillis()でほぼ一意決まってしまう。スジが良くないです。 

Info辞書のHashを準備する

Trackerでは管理しているデータをユニークなID(SHA1のハッシュ)で管理しています。 Trackerは複数のTorrentファイルを管理していることがほとんどです。 なので、TrackerはこのユニークなIDをもらい、どのピアのリストを欲しがっているか判断するのです。

なので、Trackerからピア一覧をもらう場合は、このユニークなIDを用意する必要があります。 しかし、このIDはTorrentファイルには記載されていません。 Torrentファイルから生成する必要があります。
TorrentファイルのInfo辞書のSHA1を求めてください。 それがTrackerが必要としているユニークなIDです。


例えば、以下のような感じでかける。SHA1ハッシュは既存のAPIを使用すると良いでしょう。

Reader reader = <Info辞書の部分>
byte[] temp = ....
MessageDigest md = MessageDigest.getInstance("SHA");
do {
int len = reader.read(temp);
if (len < 0) {
break;
}
md.update(temp, 0, len);
} while (true);
digestLen = md.digest(buffer, 0, 20);


その他イロイロ準備する

上記のほかにも、「Port番号」、「状態」、「ダウンロードしたバイト数」、「アップロードしたバイト数」を渡す必要があります。
- 「Port番号」
他のピアからの通信の待ち受けしているポート番号です。 

- 「状態」
Trackerに状態を通知します。 「started」、 「stopped」、 「completed」の3つがあります。
既にデータを保持している場合は、「completed」、持っていない場合は、「started」、 ネットワークから抜ける場合は、「stopped」を設定します。

アドレスを生成してみよう

HttpサーバーへリクエストするURLは使用できる文字が制限されています。しかし、今回生成した値は、限りなくランダムに近い20バイトの配列です。 このため、そのままURLに使用することはできません。 
このような場合、 Percent Encoding をしたものをURLとして使用することになっています。
Percent Encoding
URLとして使用できない文字を、 「%xx」の形式にします。xxは16進数です。
例えば、以下のような感じでかけます。

private static final char[] sEncodeMap = {
'0','1','2','3','4','5','6',
'7','8','9','A','B','C','D','E','F'};
public  String encode(byte[] input, int start, int end) {
StringBuilder mBuilder = new StringBuilder();
for(int i=start;i<end;i++) {
byte atom = input[i];
mBuilder.append(''%');
mBuilder.append(sEncodeMap[(0xF0&atom)>>4]);
mBuilder.append(sEncodeMap[atom&0xF]);
}
return mBuilder.toString()
}


URLを作る
準備した値をつなげてURLを生成しましょう。
http://xxx.xxx.xx:6969/announce?info_hash=<生成した文字列>&peer_id=<ピアID>&port=6881&uploaded=0&downloaded=0&event=started

生成したURLをブラウザに入力すれば、Trackerからピアのリストをもらえます、

P2P探訪 Raider Torrentファイルを読み込んでみる(metafile)


TorrentクローンをJava で作成しています。
そろそろ、Applet上で動作するデモができそうです。 試してみて解ったことが結構ありました。
そこで、学習したしことを、epub形式でまとめています。http://p.booklog.jp/users/kyorohiro


やる気スイッチが入らないので、書きかけの物をさらします。





-------

Torrentファイルを読み込んでみる

すでにBencodingのパーサー作成済みなので、Torrentファイルの中身を解析することができるようになったと思います。
本ページでは、Torrentファイルに記載されている情報について説明します。

.Torrentはメタファイル 

Torrentファイルのデータの中身は、metainfo file structure と呼ばれています。 「メタ」というのは、データを要約したものです。
例えば、文書であれば、 「著作名」、「題名」、「ISBN番号」といったものがあげられます。 カメラで写真を撮ると、デシタルデータの場合JPEGという方式で画像されたりします。この時、 「撮影日時」、「撮影機器」、「解像度」、「GPS情報」などが記録されます。


では、Torrentでは、どのような情報が登録されているでしょうか?

MetaInfoの構造

ファイルがひとつの時
{
   announce:<benstring>, 
   info:{
     length:<beninteger>,
     name:<benstring>,
     piece length:<beninteger>,
     pieces:<benstring>
   }
}

ファイルが複数の場合
{
   announce:<benstring>, 
   info:{
    files: [
            { length:<beninteger>, path:[<benstring>,<benstring>]},
            { length:<beninteger>, path:[<benstring>,<benstring>]},
            ..
     ]
     name:<benstring>,
     piece length:<beninteger>,
     pieces:<benstring>
   }

ファイル名を記録できる

ファイル名を記録できます。 図xxxの name でファイル名を表現します。 lengthでファイルサイズを表します。
例えば、 「dokamagi,mp4」という20MBのデータをを記録したい場合、以下のように記述できます。
info:{
  name:"dokamagi,mp4"
  length:20971529
 }
}

TorrentはひとつのMetaInfoに複数のファイルを含めることもできます。この場合、name と pathを用いてファイル名を表現します。

例えば、「data/manga/bb.zip」「data/movie/dokamagi.mp4」というデータを記録した場合は、以下のように記述できます。

info:{
  files[
    {length:20971529, movie, dokamagi.mp4}
    {length:2097152, manga, bb.mp4}
  ]
  name:"data"
  length:20971529
 }
}

Trackerのアドレスを記録できる

Trackerのアドレスが記録できます。 announce でアドレスを記述します。
例えば、「http://127.0.0.1:8080/announce」をTrackerのアドレスとして記録した場合は、
{
announce:"http://127.0.0.1:8080/announce"
}


データの分割情報を知ることができる

Torrentは、データを分割してダウンロード、アップロードします。  MetaFileには、データを分割するサイズ、そのSHA1ハッシュ値が記述されています。 分割するサイズは「piece length 」で記述します。 SHA1ハッシュは、「pieces」で記述します。
例えば、32kのデータを、16kbに分割する場合は
{
   announce:<benstring>, 
   info:{
     piece length:16384,
     pieces:<40バイトのデータ>
   }
}

piecesは、分割したデータごとにSHA1ハッシュをとります。上記の例では、データが2分割されるため、20×2の40バイトとなっています。

P2P探訪 Raider Torrentファイルを読み込んでみる(bencoding)

TorrentクローンをJava で作成しています。
そろそろ、Applet上で動作するデモができそうです。 試してみて解ったことが結構ありました。
そこで、学習したしことを、epub形式でまとめています。http://p.booklog.jp/users/kyorohiro


やる気スイッチが入らないので、書きかけの物をさらします。

-------------------------------------------------------------------

ダウンロードの始まり

データをダウンロードは、「へちまたん.torrent」といった、torrentを拡張子に持つファイルを取得することから始まります。

通常、インターネットを通じてWWWから取得することになると思います。
OSのイメージであれば配布しているサイトで手に入るかもしれません。 オープンソースアニメや著作権きれのデータなど、それ専用のデータを野止めているサイトを探すと良いでしょう。「オープンソース アニメ Torrent」、「著作権切れ Torrent」といったキーワードで検索してみてください。Googleで検索すれば簡単に見つかると思います。

このページでは、実際にTorrentファイルを読み込み。どのような情報が記載されているか調べてみましょう。

Bencode/Bencoding で書かれている

Torrentファイルはbencoding という形式で書かれています。  Torrentファイルを読み込むためには、bencodingを解釈できるようにならなくてなりません。 まずは、Bencodingを読み込んでみましょう。

String/Integer/List/Dictionaryを扱える

 bencodingは、 String/辞書/リスト の4つのデータ型を扱うことができます。
 そして、以下のようなフォーマットで書かれています。

  beninteger   : "i" [0-9]* "e"
  benstring    : [0-9]* ":" <bytes array/string> 
     # bytes array/string length is prev [0-9]*.
  bendiction   : "d" dictelements "e" 
  benlist      : "l" listelements "e"
  benobject    : beninteger | benstring | beniction | benlist
  listelements : benobject (benobject)*
  dictelements : benstring benobject (benstring benobject)*


ひとつひとつ見ていきましょう。
文字列
まずは文字列です。 この本ではbencodingでの文字列をbenstiringと呼ぶことにはます。 例えば、「torrent」という文字列は、こbenstringでは、「7:torrent」と書きます。  
また、benstringは  文字列だけでなく、バイト配列としても使われます。<20バイトの配列> は、「20:<20バイトの配列>」とあらわす事ができるのです。

整数
実数です。この本ではbencodingでの整数はbenintegerと呼ぶことにはます。例えば、「1024}という数字は、benintegerでは、[i1024e」と書くことができます。

リスト
リストとは、bencodingで扱えるデータ構造のひとつです。 0個以上のデータを順序ありでデータを保持できます。つまり、 文字、整数、リスト、辞書、を保持することができます。

この本ではbencodingでのリストはbenlistと呼ぶことにはます。
例えば、「512という数字と、"test"という文字列」は、benlistでは、[li512e4:teste」と書くことができます。                                                                                                                                           
辞書
辞書とはbencodingで扱えるデータ構造のひとつです。辞書データは文字列とデータを紐付けで管理することができます。
例えば RPGゲームで主人公のパラメータとして、名前、性別、レベル、得意な魔法、とか設定されているとします。辞書型は、主人公辞書は、"レベル"とキーを渡せば、主人公のレベルが返ります。 女の主人公ならば、"性別"とキーを渡せば、女性と返ります。

辞書です。この本ではbencodingでのリストはbendictと呼ぶことにはます。
例えば、bencodingで 「"レベル" 13」 「"magic" "halito"」 を持つ辞書は、bendictでは、[d5:levelei13e5:magic6:halitoe」と書くことができます。

パースしやすい構造になっている

bencodingはパースし易いつくりになっています。
先頭1文字で、どのデータ構造でできているかが判断できるようになっているからです。

例えば、 integerならば'i'、 stringならば's'、リストならば'l'、辞書ならば、'd' といった感じです。
なので、bencodingのdecoderは、以下のようなシナリオで実現できます。
1. 一文字読み込む。
2. どのデータか判別する。
3. データ形式に応じて読み込む。
4. 1に戻る。



今後の表記について

今後 bencodingでデーター構造を表はする場合は、以下の表記をしようします。
リスト
  「li512e4:teste」は、 「[ 512, test] 」と表記します。
辞書
  「d5:levelei13e5:magic6:halitoe」は「{level:13, magic:halito}」と表記します。

P2P探訪 Raider お互いの位置を知る

TorrentクローンをJava で作成しています。
そろそろ、Applet上で動作するデモができそうです。 試してみて解ったことが結構ありました。
そこで、学習したしことを、epub形式でまとめています。http://p.booklog.jp/users/kyorohiro


やる気スイッチが入らないので、書きかけの物をさらします。

-------------------------------------------------------------------

お互いの位置を知る

P2Pにてデータをダウンロードする場合、自分が欲しいデータを持っているコンピュータを探すことからはじまります。
これは、従来のシステムから考えると特殊なことです。たとえば、皆さんが日常で使用しているインターネットの世界では、欲しいデータの在り処はアドレスとい形で提供されています。Googleで検索したいならば、www.google.com、Youtubeで動画をみたいならば、www.youtube.com、ニコニコ動画で生放送をみたいならば、live.nicovideo.jp といったアドレスをブラウザに入力すると、欲しい情報を手に入れることができるでしょう。

しかし、P2Pではデータを持っているのは、インターネット上に名前を振られた、GoogleやYoutubeのようなホスト名を持つコンピュータではありません。今、皆さんがブラウザを起動しているようなコンピュータになります。
なので、GoogleやYoutubeにアクセスするように、皆さんのコンピュータにアクセスするためのアドレスを知る必要があります。

また、これはP2Pでのファイル共有としては重要な機能です。お互いのアドレスを知ることができれば、ほぼほぼデータ交換をに必要な作業は完了したと言っても良いでしょう。欲しいデータがあるコンピュータを知ることができたならば、後はデータ配信するようにお願いすれば良いのです。


Torrentでのお互いの位置を知る方法は2つある

では、Torrentではお互いの位置をどのようにして知るのでしょうか?Torrentでは2つの方法が提供されています。

Httpサーバーから教えてもらう方法

ひとつは、「GoogleやYoutubeのようなホスト名を持つコンピュータ」から教えてもらう方法。 このコンピュータのことをTrackerと呼びます。
P2Pといえる部分はTorrentクライアント同士がデータを転送する部分になります。 それだけではなく、TrackerはGoogleやYoutubeといったた通常のWWWのコンピュータと同じルールで動作しています。 
なので、ブラウザーからTrackerにアクセスすることも可能です。 ブラウザからTrackerにアクセスすると、データを配信してくれるTorrentクライアントの一覧を取得できます。 ためしに、以下の手順でURLを生成してTrackerにアクセスしてみてください。  TrackerはTorrentの一覧を返してくれます。
1. 
2. 
3. 
4. 
5. 

Torrentクライアント同で情報を交換しあう

 もうひとつは、「知り合いのTorrentクライアントから教えてもらう方法」です。 Mainline DHT と呼ばれていて、Kademliaベースの分散ハッシュテーブルが使用されています。 「Kademlia」については別の章で説明します。

当初TorrentはDHTをサポートしていませんでした。 このため、TorrentはTracker化が潰れてしまうとデータを配信したTorrentクライアントは存在するのに、データを配信できなません。 いかに、転送効率をあげようとも、Trackerが落ちてしまうという弱点を持っていたのです。
しかし、今では、DHTがサポートされ、Trackerが存在していなくとも、データの配信を可能にしました。


友達の友達は友達!!
DHTは「知り合いの知り合いを6人たどれば、世界中の誰とでもつながる」と同じ仕組みでできています。 例え、自分がメッセージを届けたい人のメールアドレスをしらなくても、 あなたの友人は知っているかも知れません。
友人にメッセージを届けたい人にメールアドレスを教えてもらうと良いでしょう。

もしも、 あなたの友人が「メッセージを届けたい人のメールアドレス」を知らなくても、その友人の友人は知っているかも知れません。現実世界では、「六次の隔たり」と呼ばれていて、6人もたどれば、世界中の誰とでもつながっているそうです。

DHTをサポートするTorrentクライアントは、 Torrentクライアントのリスト持っています。 もしも、特定のデータを持つTorrentクライアントを聞かれたら、自分のリストからもっともそのことを知っていそうなTorrentクライアントを紹介します。
これによって、少ない回数でおめあてのデータを持つクライアントを発見することでできるのです。

2013年7月8日月曜日

頭の体操  12個のボールから特別なボール1個を探せ!!

頭の体操  12個のボールから特別なボール1個を探せ!!


12個のボールがあります。

この12個のボールの中に重さの違う特殊ボールがひとつだけ
含まれています。

天秤を使用して3回で探し当てなさい。


[補足]

* 特殊なボールが「重いのか」「軽いのか」は知らされていません。
* 上手く計測すれば、特殊なボールが「重いのか」「軽いのか」も判るそうです。


[kyorohiroの回答]


  [手順1]. ボールにa~lの名前を振ります。

  [手順2]. 以下の用に●○×で塗りつぶします。
   a b c d e f g h i j k l
1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
   ※ 1は一回目、2は2回目に測るボールを表しています。
     「●を天秤の右側」に「○を天秤の左側」に載せてください。
  [手順3]. 手順2で指定された通りに計測してください。


[ヒント]

 * あるボールAが1回目が重くグループ & 2回目が軽いグループならば、
   Aは特殊なボールではない
 * 重いボール2つ、軽いボール1が残されたならば、重いボールどうし
   を比較すれば良い。


[検算]

   a b c d e f g h i j k l
1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎aが重いボールの時
 1回目
   「a b c d」が重くて特殊なボールの可能性
   「e f g h」が軽くて特殊なボールの可能性
 2回目
   「a」が重いボールの可能性
   「e」が軽いボールの可能性
 3回目
   「a」と「i」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎eが重いボールの時
 1回目
   「a b c d」が軽くて特殊なボールの可能性
   「e f g h」が重くて特殊なボールの可能性
 2回目
   「a」が軽いボールの可能性
   「e」が重いボールの可能性
 3回目
   「a」と「i」を比較すると答えがわかる!!




   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎bが重いボールの時
 1回目
   「a b c d」が重くて特殊なボールの可能性
   「e f g h」が軽くて特殊なボールの可能性
 2回目
   「b, c」が重いボールの可能性
   「e」が軽いボールの可能性
 3回目
   「b」と「c」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎cが重いボールの時
 1回目
   「a b c d」が重くて特殊なボールの可能性
   「e f g h」が軽くて特殊なボールの可能性
 2回目
   「b, c」が重いボールの可能性
   「e」が軽いボールの可能性
 3回目
   「b」と「c」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎dが重いボールの時
 1回目
   「a b c d」が重くて特殊なボールの可能性
   「e f g h」が軽くて特殊なボールの可能性
 2回目
   「d」が重いボールの可能性
   「f,g」が軽いボールの可能性
 3回目
   「f」と「g」を比較すると答えがわかる!!



   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎fが重いボールの時
 1回目
   「a b c d」が軽くて特殊なボールの可能性
   「e f g h」が重くて特殊なボールの可能性
 2回目
   「d」が軽くて特殊なボールの可能性
   「f,g」が重くて特殊なボールの可能性
 3回目
   「f」と「g」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎gが重いボールの時
 1回目
   「a b c d」が軽くて特殊なボールの可能性
   「e f g h」が重くて特殊なボールの可能性
 2回目
   「d」が軽くて特殊なボールの可能性
   「f,g」が重くて特殊なボールの可能性
 3回目
   「f」と「g」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎hが重いボールの時
 1回目
   「a b c d」が軽くて特殊なボールの可能性
   「e f g h」が重くて特殊なボールの可能性
 2回目
   「a」が軽くて特殊なボールの可能性
   「h」が重くて特殊なボールの可能性
 3回目
   「a」と「i」を比較すると答えがわかる!!


   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎iが重いボールの時
 1回目
   「i j k l」が特殊なボールの可能性
 2回目
   「i」が特殊なボールの可能性
 3回目
   「a」と「i」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎jが重いボールの時
 1回目
   「i j k l」が特殊なボールの可能性
 2回目
   「j,k」が重くて特殊なボールの可能性
   「l」が軽くて特殊なボールの可能性
 3回目
   「j」と「k」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎kが重いボールの時
 1回目
   「i j k l」が特殊なボールの可能性
 2回目
   「j,k」が重くて特殊なボールの可能性
   「l」が軽くて特殊なボールの可能性
 3回目
   「j」と「k」を比較すると答えがわかる!!

   a b c d e f g h i j k l

1. ●●●●○○○○××××
2. ●○○×○××●×●●○
3. ●●○××●○×○○●×
◎kが重いボールの時
 1回目
   「i j k l」が特殊なボールの可能性
 2回目
   「j,k」が軽くて特殊なボールの可能性
   「l」が重くて特殊なボールの可能性
 3回目
   「j」と「k」を比較すると答えがわかる!!

2013年7月6日土曜日

メモ

Serversman Ubuntu 10.10 で良くすること
※ 書き足すこと

●パスワードを変更
- passwd root

●ユーザーを追加
- useradd xxx
- passwd xxx

●アーカイブを古いのにする
- vi /etc/apt/sources.listc
>
>deb http://archive.ubuntu.com/ubuntu maverick main restricted universe
>deb http://archive.ubuntu.com/ubuntu maverick-updates main restricted universe
>deb http://archive.ubuntu.com/ubuntu maverick-security main restricted universe

deb http://old-releases.ubuntu.com/ubuntu maverick main restricted universe
deb http://old-releases.ubuntu.com/ubuntu maverick-updates main restricted universe
deb http://old-releases.ubuntu.com/ubuntu maverick-security main restricted universe

- apt-get update
- apt-get upgrade


● xbuntuをインストール
- apt-get install xubuntu-desktop

● vncインストール/起動
- apt-get install vnc4server
- vncpasswd
- 一度クライアントから接続
- vi .vnc/xstartup

>
>#!/bin/sh
>
># Uncomment the following two lines for normal desktop:
># unset SESSION_MANAGER
># exec /etc/X11/xinit/xinitrc
>
>[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
>[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
>xsetroot -solid grey
>vncconfig -iconic &
>x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
>x-window-manager &
>

#!/bin/sh
# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
x-window-manager &
startxfce4 &

- vncserver 
- ssh転送で接続



● javafxインストール
- echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" | tee -a /etc/apt/sources.list
- echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" | tee -a /etc/apt/sources.list
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886
- apt-get update
- apt-get install oracle-java7-installer
- apt-get install oracle-java7-set-default

ref http://www.webupd8.org/2012/06/how-to-install-oracle-java-7-in-debian.html


● ssh 接続制限
- vi /etc/ssh/sshd_config
Port xxx
PermitRootLogin no

- /etc/init.d/ssh restart

●git インストール
- apt-get install git-core
- apt-get install gitk

●eclipse インストール
- eclipseのサイトから
- 起動->help->install new software
  http://www.efxclipse.org/p2-repos/releases/latest/
  http://download.eclipse.org/mat/1.3/update-site/
- 起動->help->Marketplace
  http://update.eclemma.org/


●Dキーが使えない問題の対処
- https://forums.ubuntulinux.jp/viewtopic.php?id=9647


●githubの設定
- git config --global user.name 
- git config --global user.email 
- ssh-keygen -t rsa -C 


○ボート
ssh -N -L <転送元ポート>:<転送元アドレス>:<転送先ボート> <転送先アドレス> -l <SSHユーザー名> -p <SSHポート>