continued BotLoader, added ModManager.class.php & timers
[PHP-P10.git] / Uplink / Numerics.class.php
1 <?php
2 /********************************* PHP-P10 ******************************
3  *    P10 uplink class by pk910   (c)2011 pk910                         *
4  ************************************************************************
5  *                          Version 2 (OOP)                             *
6  *                                                                      *
7  * PHP-P10 is free software; you can redistribute it and/or modify      *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or    *
10  * (at your option) any later version.                                  *
11  *                                                                      *
12  * This program is distributed in the hope that it will be useful,      *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
15  * GNU General Public License for more details.                         *
16  *                                                                      *
17  * You should have received a copy of the GNU General Public License    *
18  * along with PHP-P10; if not, write to the Free Software Foundation,   *
19  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.       *
20  *                                                                      *
21  ************************************************************************
22  * 
23  *  Uplink/Numerics.class.php
24  *
25  * P10 numeric functions
26  *
27  ************************************************************************
28  * accessable functions
29  *
30  * static String intToNum(int $int, int $length)
31  *     returns the numeric representing $int
32  *
33  * static int numToInt(String $numeric)
34  *     returns the integer value, the numeric represents
35  *
36  * static String parseIP(String $numeric)
37  *     parses an IP Address in numeric format
38  *
39  * static String numericFromIP(String $ip)
40  *     builds a numeric representing the IP
41  */
42
43 class Numerics {
44         private static $base64chars = array(
45           'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
46           'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
47           'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
48           'w','x','y','z','0','1','2','3','4','5','6','7','8','9','[',']'
49         );
50         private static $base64charsLength = 64;
51         
52         public static function intToNum($int, $length) {
53                 //fix a small "bug": normaly 0 = AAAAA but we need 1 = AAAAA
54                 $int = $int - 1;
55                 
56                 $numeric = "";
57                 for($pos = $length-1; $pos >= 0; $pos--) {
58                         //current position represents floor($int / ($base64charsLength ^ $pos))
59                         $base = 1;
60                         for($i = 0; $i < $pos; $i++) {
61                                 $base = $base * self::$base64charsLength;
62                         }
63                         $posValue = floor($int / $base);
64                         //get the char representing $posValue
65                         $posChar = self::$base64chars[$posValue];
66                         $numeric .= $posChar;
67                 }
68                 
69                 return $numeric;
70         }
71         
72         public static function numToInt($numeric) {
73                 $base = 1;
74                 $int = 0;
75                 for($pos = strlen($numeric)-1; $pos >= 0; $pos--) {
76                         $posValue = array_search($numeric[$pos], self::$base64chars);
77                         $int = ($posValue * $base);
78                         $base = $base * self::$base64charsLength;
79                 }
80                 
81                 //fix a small "bug": normaly 0 = AAAAA but we need 1 = AAAAA
82                 $int = $int + 1;
83                 
84                 return $int;
85         }
86         
87         public static function parseIP($numeric, $shortForm = true) {
88                 if(strlen($numeric) == 6) { //IPv4
89                         $value = self::numToInt($numeric);
90                         $ip = array();
91                         $ip[0] = ($value & 0xff000000) >> 24;
92                         $ip[1] = ($value & 0x00ff0000) >> 16;
93                         $ip[2] = ($value & 0x0000ff00) >> 8;
94                         $ip[3] = ($value & 0x000000ff);
95                         return implode(".", $ip);
96                 } else { //IPv6
97                         $ip = array();
98                         for($i = 0; $i < strlen($numeric);) {
99                                 if($numeric[$i] == "_") {
100                                         if($shortForm) {
101                                                 $ip[] = ""; //::
102                                         } else {
103                                                 $rightBlocks = (strlen($numeric) - ($i + 1)) / 3;
104                                                 $skipCount = 8 - count($ip) - $rightBlocks;
105                                                 for($j = 0; $j < $skipBlocks; $j++) {
106                                                         $ip[] = "0";
107                                                 }
108                                         }
109                                         $i++;
110                                 } else {
111                                         $value = self::numToInt($numeric[$i].$numeric[$i+1].$numeric[$i+2]);
112                                         $ip[] = dechex($value);
113                                         $i += 3;
114                                 }
115                         }
116                         return implode(":", $ip);
117                 }
118         }
119         
120         public static function numericFromIP($ip) {
121                 $pattern = array();
122                 $pattern['ipv6'] = '/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))(|\/[0-9]{1,3})$/';
123                 $pattern['ipv4'] = '/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(|\/[0-9]{1,2})$/';
124                 if(preg_match($pattern['ipv4'], $ip)) {
125                         //thats quite simple here
126                         $ip = explode(".", $ip);
127                         $ipValue = intval($ip[3]);
128                         $ipValue <<= 8;
129                         $ipValue |= intval($ip[2]);
130                         $ipValue <<= 8;
131                         $ipValue |= intval($ip[1]);
132                         $ipValue <<= 8;
133                         $ipValue |= intval($ip[0]);
134                         $ip = self::intToNum($ipValue,6);
135                 } else if(preg_match($pattern['ipv6'], $ip)) {
136                         //thats a little bit complicated :D (we may only have one _)
137                         $ipv6 = array();
138                         $ip = explode(":",$ip);
139                         $last_zero = false; $zero_sequence = 0; $biggest_zero_sequence = 0; $max_start = -1;
140                         $i = 0;
141                         foreach($ip as $v) {
142                                 if($v == "") {
143                                         $skipBlocks = (8 - count($ip));
144                                         for($j = 0; $j < $skipBlocks; $j++) {
145                                                 $ipv6[$i+$j] = "_";
146                                         }
147                                         $max_start = $i;
148                                         if($last_zero) {
149                                                 $zero_sequence += $skipBlocks;
150                                         } else {
151                                                 $last_zero = true;
152                                                 $zero_sequence = $skipBlocks;
153                                         }
154                                         $i+=$skipBlocks;
155                                         if($zero_sequence > $biggest_zero_sequence) {
156                                                 $biggest_zero_sequence = $zero_sequence;
157                                                 $max_start = $i-($zero_sequence-1);
158                                         }
159                                 } else {
160                                         $value = hexdec($v);
161                                         if($value == 0) {
162                                                 $ipv6[$i] = "_";
163                                                 if($last_zero) {
164                                                         $zero_sequence++;
165                                                 } else {
166                                                         $last_zero = true;
167                                                         $zero_sequence = 1;
168                                                 }
169                                                 if($zero_sequence > $biggest_zero_sequence) {
170                                                         $biggest_zero_sequence = $zero_sequence;
171                                                         $max_start = $i-($zero_sequence-1);
172                                                 }
173                                         } else {
174                                                 $ipv6[$i] = self::intToNum($value,3);
175                                                 $last_zero = false;
176                                         }
177                                         $i++;
178                                 }
179                         }
180                         $ip = "";
181                         for($i = 0; $i < 8; $i++) {
182                                 if($i == $max_start) { //merge the biggest sequence of _'s
183                                         $ip .= "_";
184                                         $i += ($biggest_zero_sequence-1);
185                                 } elseif($ipv6[$i] == "_") {
186                                         $ip .= "AAA";
187                                 } else {
188                                         $ip .= $ipv6[$i];
189                                 }
190                         }
191                         return $ip;
192                 } else {
193                         $ip = "AAAAAA";
194                 }
195                 return $ip;
196         }
197         
198 }
199
200 ?>