かれ4

かれこれ4個目のブログ

IPアドレスの割当を視覚化してみた

別のブログで書こうと思ってる記事の為に、IPアドレスの分布を図にしてみた。

今回必要だったのはAPNICとJPNICだけだったけれど、
ついでなのでIANAの直下5個(APNIC,ARIN,LACNIC,RIPENCC,AFRINIC)全部を図にしてみた。

読み方は、y軸が第1オクテット x軸が第2オクテット
グリッドの中が16x16の256のドットがあって左上から右下に向かって第3オクテットを表します。



国毎の分布

図1. 世界のIPアドレス割当 (国別)


RIR毎の分布

図2. 世界のIPアドレス割当 (地域別)


ついでにAPNIC管轄のIPアドレス 赤い所が日本に割り当てられてるIPアドレス 灰色の所は他のAPNIC

図3. 日本のIPアドレス

ソースは2011/7/26時点のこちら

ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-latest         apnic アジア・太平洋地域
ftp://ftp.arin.net/pub/stats/arin/delegated-arin-latest          arin アメリカ北部圏
ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest             lacnic ラテンアメリカ及び西インド諸島地域
ftp://ftp.ripe.net/ripe/stats/delegated-ripencc-latest      ripencc ヨーロッパ地域
ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-latest         afrinic アフリカ地域

この画像を作ったプログラムのソースはこちら
PHP5.3 +GD

<?php
    
$map = new IPMap();
// IPMap::create(inputfile,class,outputfile);
$map->create('./delegated-all-latest','country','map-all.png');
$map = null;

class IPMap{
     private $colors = array();
     private $gd;
     const MARGIN = 100;
     public function __construct(){
          $this->gd = imagecreate(256*17+self::MARGIN+20,256*17+self::MARGIN+40);
     }

     public function create($file,$division='countory',$outputfile='map.png'){
          $this->drawGrid($this->gd);
          $fp = fopen($file,'r');
          while($fp !== false && !feof($fp)){
               $buf = fgets($fp,4096);
               $cell = explode('|',$buf);
               if(count($cell) === 7){
                    if($cell[2] === 'ipv4'){
                         if($division !== 'nic'){
                              $color = $this->getColor($cell[1]);
                         }else{
                              $color = $this->getColor($cell[0]);
                         }
                         $address = $cell[3];
                         $oct = explode('.',$address);
                         $this->map($this->gd,$oct[0],$oct[1],$oct[2],$cell[4],$color);
                    }
               }
          }
          imagepng($this->gd,$outputfile);
          ImageDestroy($this->gd);
          fclose($fp);
     }

     private function drawGrid($image){
          $white = imagecolorallocate($image,255,255,255);
          imagefilltoborder($image,0,0,$white,$white);
          $black = imagecolorallocate($image,140,140,140);
          for($i = 0; $i < 256;$i++){
               // v
               $y = ($i%2==0)?(self::MARGIN-20):(self::MARGIN-35);
               imagestring($image,4,$i*17+self::MARGIN,$y,$i,$black);
               imageline($image,$i*17+self::MARGIN,self::MARGIN,$i*17+self::MARGIN,256*17+self::MARGIN,$black);
               // h
               imagestring($image,4,self::MARGIN-30,$i*17+self::MARGIN,$i,$black);
               imageline($image,self::MARGIN-30,$i*17+self::MARGIN,256*17+self::MARGIN,$i*17+self::MARGIN,$black);
          }    
          imageline($image,$i*17+self::MARGIN,self::MARGIN,$i*17+self::MARGIN,256*17+self::MARGIN,$black);
          imageline($image,self::MARGIN-30,$i*17+self::MARGIN,256*17+self::MARGIN,$i*17+self::MARGIN,$black);
     }
    
     private function map($image,$first,$second,$third,$count,$color){
          $blockY = $first*17+1+self::MARGIN;
          $blockX = $second*17+1+self::MARGIN;
          $blockindex = 0;
          $lineindex = floor($third/16);
          $shift = $third%16;
          $c = $count / 256;
          for($i=0;$i<$c;$i++){
               if($i !== 0 && $shift == 16 ){
                    // line feed
                    $lineindex++;
                    $shift = 0;
               }
               if($i !== 0 && $i % 256 == 0){
                    // block shift
                    $blockindex++;
                    $shift = 0;
                    $lineindex = 0;
               }
               $y = $blockY + $lineindex;
               $x = $blockX + $blockindex * 17 + $shift;
               imageline($image,$x,$y,$x,$y,$color);
               $shift++;
          }
     }
    
     private function getColor($code){
          if(!isset($this->colors[$code])){
               $n = hexdec(bin2hex($code));
               // ここをいじれば、色遣いがもっと美しくなるはず。
               $r = floor($n*23)%256;
               $g = floor($n*13)%256;
               $b = floor($n*33)%256;
               echo "$code($n) -> rgb($r,$g,$b)  \n";
               $color = imagecolorallocate($this->gd,$r,$g,$b);
               $this->colors[$code] = $color;
               $y = floor(count($this->colors)*30/4000) * 20 + 10;
               $x = (count($this->colors)*30)%4000 + self::MARGIN;
               imagestring($this->gd,5,$x,$y,$code,$color);
          }
          return $this->colors[$code];
     }
}