11<?php
22
33/*
4- * Copyright (C) 2005-2015 IP2Location.com
4+ * Copyright (C) 2005-2016 IP2Location.com
55 * All Rights Reserved
66 *
77 * This library is free software: you can redistribute it and/or
@@ -32,7 +32,7 @@ class Database {
3232 *
3333 * @var string
3434 */
35- const VERSION = '7.2.3 ' ;
35+ const VERSION = '7.2.4 ' ;
3636
3737 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3838 // Error field constants ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -977,8 +977,13 @@ private static function ipVersionAndNumber($ip) {
977977 if (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 )) {
978978 return [4 , sprintf ('%u ' , ip2long ($ ip ))];
979979 } elseif (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 )) {
980- // Use bcBin2Dec to deal with BCMath ints
981- return [6 , self ::bcBin2Dec (inet_pton ($ ip ))];
980+ $ result = 0 ;
981+
982+ foreach (str_split (bin2hex (inet_pton ($ ip )), 8 ) as $ word ) {
983+ $ result = bcadd (bcmul ($ result , '4294967296 ' , 0 ), self ::wrap32 (hexdec ($ word )), 0 );
984+ }
985+
986+ return [6 , $ result ];
982987 } else {
983988 // Invalid IP address, return falses
984989 return [false , false ];
@@ -994,13 +999,19 @@ private static function ipVersionAndNumber($ip) {
994999 * @return string
9951000 */
9961001 private static function bcBin2Dec ($ data ) {
997- $ result = '0 ' ;
998- // At each step, take a 32 bit hex value, get its decimal equivalent,
999- // and add it to the result of multiplying the accumulated result by
1000- // 2^32 (to "move" it a word's worth)
1001- foreach (str_split (bin2hex ($ data ), 8 ) as $ word ) {
1002- $ result = bcadd (bcmul ($ result , '4294967296 ' , 0 ), self ::wrap32 (hexdec ($ word )), 0 );
1003- }
1002+ $ parts = array (
1003+ unpack ('V ' , substr ($ data , 12 , 4 )),
1004+ unpack ('V ' , substr ($ data , 8 , 4 )),
1005+ unpack ('V ' , substr ($ data , 4 , 4 )),
1006+ unpack ('V ' , substr ($ data , 0 , 4 )),
1007+ );
1008+
1009+ foreach ($ parts as &$ part )
1010+ if ($ part [1 ] < 0 )
1011+ $ part [1 ] += 4294967296 ;
1012+
1013+ $ result = bcadd (bcadd (bcmul ($ parts [0 ][1 ], bcpow (4294967296 , 3 )), bcmul ($ parts [1 ][1 ], bcpow (4294967296 , 2 ))), bcadd (bcmul ($ parts [2 ][1 ], 4294967296 ), $ parts [3 ][1 ]));
1014+
10041015 return $ result ;
10051016 }
10061017
@@ -1464,9 +1475,9 @@ private function binSearch($version, $ipNumber) {
14641475
14651476 // as long as we can narrow down the search...
14661477 while ($ low <= $ high ) {
1467- // be careful with midpoint calculation
14681478 $ mid = (int ) ($ low + (($ high - $ low ) / 2 ));
1469- // Read IP ranges to get boundaries
1479+
1480+ // Read IP ranges to get boundaries
14701481 $ ip_from = $ this ->readIp ($ version , $ base + $ width * $ mid );
14711482 $ ip_to = $ this ->readIp ($ version , $ base + $ width * ($ mid + 1 ));
14721483
0 commit comments