"); } while($left<=$right){ $index=intval(($left+$right)/2); $realIndex=$index*3; if($debug){ //debugEcho("[".$array[$realIndex]." ".$string." ". // strcmp($array[$realIndex],$string)." ". // $array[$realIndex+1]." ".$array[$realIndex+2]."]
"); } $cmp=strcmp($array[$realIndex],$string); if($cmp==0){ return array($array[$realIndex+1],$array[$realIndex+2]); } else if ($cmp<0){ $left=$index+1; } else { $right=$index-1; } } return false; } function stripStringAtEnd($ua,$string){ $stringlen=strlen($string); $ualen=strlen($ua); if($ualen>=$stringlen && substr($ua,$ualen-$stringlen)==$string){ $ua=substr($ua,0,$ualen-$stringlen); } return $ua; } function isObscureDesktop($ua){ if(strpos($ua,"Mozilla/5.0 (compatible; Konqueror/")===0|| // KDE; Version no. follows "Konqueror/" strpos($ua," (MacBook")!==false|| // ex. MacBook3%2C1 (strpos($ua,"Opera/")===0 && strpos($ua," (Linux")!==false) || (preg_match("/^Opera\\/(8|9|\\d\\d+)\\.\\d+ \\(Windows NT \\d+\\.\\d/",$ua)) || strpos($ua,"Windows ME")!==false|| strpos($ua,"Mac_PowerPC")!==false ){ return true; } return false; } function isOldBrowser($ua){ if(strpos($ua,"Mozilla/")===0){ // Old Internet Explorer if(preg_match("/^Mozilla\\/1\\.22 \\(compatible; MSIE 2\\.0; [^\\)]+\\)$/",$ua) || preg_match("/^Mozilla\\/2\\.0 \\(compatible; MSIE 3\\.0[abB12]; [^\\)]+\\)$/",$ua) || preg_match("/^Mozilla\\/3\\.0 \\(compatible; MSIE 4\\.0p1; [^\\)]+\\)$/",$ua) || preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE 4\\.0(b1|b2|1)?; [^\\)]+\\)$/",$ua) || preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE 5\\.(0|0b1|01|5); [^\\)]+\\)$/",$ua)) { // May include "AOL 3.0" in extra data, ignore UAs with 'Windows CE' if(strpos($ua,"Windows CE")===false){ return true; } } // Mozilla 1, 2, or 3 with no language if(preg_match("/^Mozilla\\/[123]\\.\\d+\\S* \\((Win95|Win98|WinNT|X11|Win16); [IU][^\\)]*\\)$/",$ua)){ return true; } // Mozilla 3 or 4 with language if(preg_match("/^Mozilla\\/[34]\\.\\d+\\S* \\[\\w\\w\\] \\((Win95|Win98|WinNT|X11|Win16); [IU][^\\)]*\\)$/",$ua)){ return true; } // Mozilla 4 for Mac if(preg_match("/^Mozilla\\/4\\.\\d+\\S* \\(Macintosh; [IU][^\\)]*\\)$/",$ua)){ return true; } } if($ua=="Mozilla/2.0 (compatible; NetPositive; BeOS)"|| strpos($ua,"aolbrowser/1.1")===0|| strpos($ua,"IWENG/1.2.003")===0|| strpos($ua,"IBM-WebExplorer-DLL/v")===0|| strpos($ua,"Mozilla/2.0 (compatible; MS FrontPage 4.0)")===0|| strpos($ua,"NCSA Mosaic/")===0|| strpos($ua,"Mozilla/3.0 (compatible; Opera/")===0|| // Version no. follows "Opera/" strpos($ua,"Mozilla/2.0 (Sextant v")===0|| // Version no. follows "Sextant v" strpos($ua,"HotJava/1.1 FCS")===0|| strpos($ua,"OmniWeb/")===0|| strpos($ua,"Mozilla/2.0 (compatible; AOL 3.0")===0|| strpos($ua,"Emacs-W3/")===0|| strpos($ua,"Mozilla/2.0 (Compatible; AOL-IWENG 3.0")===0|| preg_match("/^Lynx[ \\/]2[-\\.]\\d[-\\.\\d]*\\S*\\s+/",$ua) // Lynx browser ){ return true; } return false; } // Determines whether a user-agent matches a very common user agent string // (Internet Explorer, Firefox, Safari, Opera). Only UAs for desktop operating // systems are checked (e.g. Windows, Linux, Macintosh). function isVeryWellKnown($ua){ if(strpos($ua,"Mozilla/5.0 (")===0){ // Firefox on Windows or X11; BonEcho, DeerPark, and Minefield are prerelease codenames $ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)"); $ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)"); if(preg_match("/^Mozilla\\/5\\.0 \\((Windows|X11); U; [^;]+; \\w+(?:-\\w+)?; rv:\\d[\\d\\.ab]+\\) Gecko\\/\\d{8,12} [^\\(]*?(Camino|BonEcho|DeerPark|Minefield|Firefox|Netscape)\\/\\d[\\d\\.ab]+/",$ua)){ return true; } if(preg_match("/^Mozilla\\/5\\.0 \\((Windows|X11); U; [^;]+; \\w+(?:-\\w+)?; rv:\\d[\\d\\.ab]+\\) Gecko\\/\\d{8,12} Ubuntu\\/\\d[\\d\\.ab]+.*? (Camino|BonEcho|DeerPark|Minefield|Firefox|Netscape)\\/\\d[\\d\\.ab]+/",$ua)){ return true; } // Firefox on Mac if(preg_match("/^Mozilla\\/5\\.0 \\(Macintosh; U; (Intel|PPC)(?: Mac OS X[^;]*)?; \\w+(?:-\\w+)?; rv:\\d[\\d\\.]+\\) Gecko\\/\\d{8,12} [^\\(]*?(BonEcho|DeerPark|Minefield|Firefox|Netscape)\\/\\d[\\d\\.ab]+/",$ua)){ return true; } // Safari on Windows if(preg_match("/^Mozilla\\/5\\.0 \\(Windows; U; Windows NT \\d+\\.\\d; \\w+(?:-\\w+)?\\) ". "AppleWebKit\\/\\d[\\d\\.]+ \\(KHTML, like Gecko\\)(?: Version\\/\\d[\\d\\.]+)? .*?Safari\\/\\d[\\d\\.]+$/",$ua)){ // May contain Chrome/[version] return true; } // Safari on Mac if(preg_match("/^Mozilla\\/5\\.0 \\((Macintosh); U; (Intel|PPC) Mac OS X( 10(_\\d+(?:_\\d+)?))?; \\w+(?:-\\w+)?\\) ". "AppleWebKit\\/\\d[\\d\\.]+ \\(KHTML, like Gecko\\)(?: Version\\/\\d[\\d\\.]+)? .*?Safari\\/\\d[\\d\\.]+$/",$ua)){ // May contain Chrome/[version] return true; } } else if(strpos($ua,"Mozilla/4.0 (compatible; MSIE ")===0){ // IE on Windows NT $ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)"); $ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)"); $matches=array(); if(preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE (5\\.5|6\\.0|7\\.0|8\\.0); Windows NT \\d+\\.\\d(\\)|; (.+?)\\))$/",$ua)){ return true; } // IE Quirks Mode if(preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE (6\\.0|7\\.0|8\\.0); Windows NT \\d+\\.\\d; ([^;\\)]*; )*?Mozilla\\/4\\.0 \\(compatible; MSIE 6\\.0; Windows NT 5\\.1; SV1\\) ?(; [^\\;\\)]*)*\\)$/" ,$ua)){ return true; } } else if(strpos($ua,"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1")===0){ if(preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE (5\\.5|6\\.0|7\\.0|8\\.0); Windows NT \\d+\\.\\d(\\)|; [^\\)]+\\))$/",$ua)){ return true; } } else if(strpos($ua,"Opera/")===0){ // Opera on Windows NT $ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)"); $ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)"); if(preg_match("/^Opera\\/(8|9|\\d\\d+)\\.\\d+ \\(Windows NT \\d+\\.\\d; U; \\w+(?:-\\w+)?\\)( Presto\\/\\d[\\d\\.]+)?/",$ua)){ return true; } // Opera on Mac if(preg_match("/^Opera\\/(8|9|\\d\\d+)\\.\\d+ \\(Macintosh; (Intel|PPC) Mac OS X; U; \\w+(?:-\\w+)?\\)( Presto\\/\\d[\\d\\.]+)?/",$ua)){ return true; } } return false; } function isConsole($ua){ return getBrowserType($ua)==3; } /* Returns the type of user agent represented in a user agent string: 0 - Banned (malicious bots) 1 - Bot (beneficial bots) 2 - Handheld mobile device 3 - Game console (relatively high resolution, but no keyboard; e.g. PLAYSTATION 3; Wii) 4 - Desktop browser (Internet Explorer, Firefox, Opera, etc.) 5 - Unknown (can be treated like bots) */ function getBrowserType($ua){ $ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)"); $ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)"); // Check for common browsers if(isVeryWellKnown($ua)) return 4; // Check for banned browsers if(isBanned($ua)) return 0; if(preg_match("/Nintendo Wii|Wii Shop Channel|PLAYSTATION 3/",$ua)) // Game console return 3; // Check for bots if(isBot($ua)) return 1; // Check for other kinds of desktop browsers if(isWellKnown($ua) || isOldBrowser($ua) || isObscureDesktop($ua)) return 4; // Check for mobile browsers if(isMobile($ua)) return 2; // Unknown browser return 5; } function isWellKnown($ua){ $op9=strpos($ua,"Opera/9"); if($op9!==false && $op9>0) return false; if(strpos($ua,"HTC")===0) return false; if(strpos($ua,"; Windows NT ")!==false|| strpos($ua,"Mozilla/4.0 (compatible; MSIE 7.0")!==false|| strpos($ua,"Mozilla/4.0 (compatible; MSIE 8.0")!==false|| strpos($ua,"; Windows 95")!==false|| strpos($ua,"MSIE 999.1")!==false|| // used in stealthing strpos($ua,"Windows ME")!==false|| strpos($ua,"(X11; U; ")!==false|| strpos($ua," Firefox/")!==false|| strpos($ua,"Intel Mac OS X")!==false|| strpos($ua,"; Linux i686;")!==false|| strpos($ua,"; Linux x86_64;")!==false|| strpos($ua,"PPC Mac OS X")!==false ) return true; if(strpos($ua,"Windows 98")!==false && strpos($ua,"PalmSource")===false) // Palm browsers use Windows 98 moniker return true; return false; } // Determines whether a user agent represents a bot function isBot($ua){ global $bots; // Treat empty and too-short UAs as bots if(strlen($ua)<=2)return true; // Bots are not mobile browsers for($i=0;$i100 ? 102400 : $cache[1]*1024; } return 5*1024; } else if(preg_match("/^Mozilla\\/(5\\.0|4\\.08)\\s+\\(([\\w\\+]+);FOMA;([^\\)]+)\\)/",$ua,$matches)){ // FOMA $tokens=explode(";",$matches[1]); if($tokens[0] && preg_match("/^c(\\d+)$/",$tokens[0],$cache)){ // cache size return $cache[1]*1>100 ? 102400 : $cache[1]*1024; } return 5*1024; } else if(IsSoftBank($ua)!=""){ if(preg_match("/^J-PHONE\\/(\\d+)/",$ua,$matches)){ if($matches[1]=="3")return 6*1024; if($matches[1]=="4")return 12*1024; if($matches[1]=="5")return 40*1024; return 6*1024; } return 9*1024; } else if(preg_match("/^(?:DOCOMO|DoCoMo|portalmmm)\\/2\\.0\\s+([\\w\\+]+)\\(([^\\)]+)\\)/",$ua,$matches)){ // Docomo phone 2.0 $model=$matches[1]; $tokens=explode(";",$matches[2]); $cache=array(); if($tokens[0] && preg_match("/^c(\\d+)$/",$tokens[0],$cache)){ // cache size $maxsize=$cache[1]; if($maxsize>30){ $maxsize=30; } return $maxsize*1024; } return 10*1024; } // For other browsers, guess maximum from screen size $size=getScreenSize($ua); if($size[0]>=800 && $size[1]>=600){ // high resolution return 200000; } // unknown screen size if($size[0]==-1 || $size[1]==-1){ return 4096; } $suggestedMaxSize=$size[0]; // width $suggestedMaxSize*=$size[1]; // height $suggestedMaxSize*=4; $suggestedMaxSize/=27; $suggestedMaxSize=floor($suggestedMaxSize); if($suggestedMaxSize>20000){ $suggestedMaxSize=20000; } if($suggestedMaxSize<4096){ $suggestedMaxSize=4096; } return $suggestedMaxSize; } // Guesses the screen size given information in // the user request function getScreenSizeThis(){ // Try parsing the HTTP headers first $display=$_SERVER['HTTP_X_JPHONE_DISPLAY']; if(isset($display)){ $matches=array(); if(preg_match("/^\\s*(\\d+)\\*(\\d+)/",$display,$matches)){ return array($matches[1]*1,$matches[2]*1); } } $display=$_SERVER['HTTP_X_EMULATOR_DISPLAY']; if(isset($display)){ $matches=array(); if(preg_match("/^\\s*(\\d+)\\*(\\d+)/",$display,$matches)){ return array($matches[1]*1,$matches[2]*1); } } $display=$_SERVER['HTTP_X_UP_DEVCAP_SCREENPIXELS']; if(isset($display)){ $matches=array(); if(preg_match("/^\\s*(\\d+)\\s*[,x]\\s*(\\d+)/",$display,$matches)){ return array($matches[1]*1,$matches[2]*1); } } $display=$_SERVER['HTTP_UA_PIXELS']; if(isset($display)){ $matches=array(); if(preg_match("/^\\s*(\\d+)\\s*[,x]\\s*(\\d+)/",$display,$matches)){ return array($matches[1]*1,$matches[2]*1); } } $display=$_SERVER['HTTP_X_SKYFIRE_SCREEN']; if(isset($display)){ $matches=array(); // fullscreenWidth,fullscreenHeight,canvasWidth,canvasHeight if(preg_match("/^\\s*(\\d+),(\\d+),(\\d+),(\\d+)/",$display,$matches)){ return array($matches[3]*1,$matches[4]*1); } } $display=$_SERVER['HTTP_X_OS_PREFS']; if(isset($display)){ $matches=array(); $ret=array(128,128); if(preg_match("/fw\\:(\\d+)/",$display,$matches)){ $ret[0]=$matches[1]*1; } if(preg_match("/fh\\:(\\d+)/",$display,$matches)){ $ret[1]=$matches[1]*1; } return $ret; } $display=$_SERVER['HTTP_X_S_DISPLAY_INFO']; if(isset($display)){ $matches=array(); // canvas size/character size/TB or TC if(preg_match("/^\\s*(\\d+)\\*(\\d+)\\/(\\d+)\\*(\\d+)\\/(TB|TC)/",$display,$matches)){ return array($matches[1]*1,$matches[2]*1); } } // Try deriving the screen size from the user agent return getScreenSize(getRealUserAgent()); } function supportsImagesThis(){ // Try parsing the HTTP headers first $display=$_SERVER['HTTP_X_S_DISPLAY_INFO']; if(isset($display)){ $matches=array(); // canvas size/character size/TB or TC if(preg_match("/^\\s*(\\d+)\\*(\\d+)\\/(\\d+)\\*(\\d+)\\/(TB|TC)/",$display,$matches)){ return $matches[5]=="TB"; } } return supportsImages(getRealUserAgent()); } function supportsImages($ua){ // All very well known UAs support images if(isVeryWellKnown($ua)) return true; // Lynx is text-based if(preg_match("/^Lynx[ \\/]2[-\\.]\\d[-\\.\\d]*\\S*\\s+/",$ua)){ return false; } if(preg_match("/^(DOCOMO|DoCoMo)\\/1\\.0\\//",$ua)){ // Docomo phone 1.0 $tokens=explode("/",$ua); // If fifth token is TC (as opposed to TB or absent), images are disabled if($tokens[4]=="TC")return false; } else if(preg_match("/^Mozilla\\/4\\.08\\s+\\(([\\w\\+]+);FOMA;([^\\)]+)\\)/",$ua,$matches)){ // FOMA $model=$matches[0]; $tokens=explode(";",$matches[1]); if($tokens[1]=="TC"){ return false; } } else if(preg_match("/^(?:DOCOMO|DoCoMo|portalmmm)\\/2\\.0\\s+([\\w\\+]+)\\(([^\\)]+)\\)/",$ua,$matches)){ // Docomo phone 2.0 $model=$matches[1]; $tokens=explode(";",$matches[2]); if($tokens[2]=="TC"){ // images are disabled } } return true; } // Guesses the screen size given a user agent string function getScreenSize($ua,$debug/*def*/=false/*enddef*/){ global $docomo; global $dimensions; global $dimensionsExact; global $MobilePhone; global $nonwireless; global $kddi; global $softbank; global $openwave; global $cldc; global $devices; // well-known browsers if(isWellKnown($ua) || $ua=="") return array(-1,-1); if($ua=="UNTRUSTED/1.0") // J2ME application return array(200,200); if(preg_match("/^MobileSafari\\//",$ua)) // iPhone/iPod helper UA return array(320,396); if(preg_match("/^UP\\.Link\\/[\\d\\.]+$/",$ua)) // Unknown return array(200,200); $ua=clipDevice($ua); $matches=array(); $fallback=array(-1,-1); if(strpos($ua,"Opera Mini")!==false || strpos($ua,"(compatible; OpenWeb ")!==false || $ua=="Skyfire Downloader"){ // Opera Mini/Skyfire hides user agent info return array(200,200); } else if(preg_match("/^PDXGW\\/[0-9\\.]+\s*\\(([^\\)]+)\\)/",$ua,$matches)){ // PDXGW/1.0 (TX=8;TY=7;GX=96;GY=84;C=C256;G=BF;GI=2) // C=CF means C=65536; C=G2 means C=C2 $tokens=explode(";",$matches[1]); $ret=array(200,200); for($i=0;$i"); if(preg_match("/^(.*?)([ \\/\\*]|$)/",$ua,$matches)){ //if($debug)debugEcho("common: ".$matches[1]."
"); $ret=searchWidthHeightExact($cldc,$matches[1],$debug); if($ret!==false)return $ret; $ret=searchWidthHeightExact($openwave,$matches[1]); if($ret!==false)return $ret; $ret=searchWidthHeightExact($devices,$matches[1]); if($ret!==false)return $ret; } } else if(preg_match("/^Mozilla\\/4\\.0 \\(MobilePhone ([A-Z]+-?\\d+)\\//",$ua,$matches)){ $model=$matches[1]; $ret=searchWidthHeightExact($MobilePhone,$model); if($ret!==false) return $ret; } else if( preg_match("/^UP\\.Browser\\/(?:[\\d\\._A-Za-z]+)\\s+(KDDI-\\w+)/",$ua,$matches) || // HDML preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE 6\\.0; (KDDI-\\w+)/",$ua,$matches) ){ $model=$matches[1]; $ret=searchWidthHeightExact($openwave,$model); if($ret===false) return array(-1,-1); return $ret; } else if(preg_match("/^([^\\/\\s\\*]+)(?:\\*[^\\/\\s]*)?(?:\\/\\S*)? UP\\.Browser\\/(\\d+[\\d\\._A-Za-z]+) (\\(GUI\\) )?MMP\\/\\d+\\.\\d+/",$ua,$matches)){ $model=$matches[1]; $ret=searchWidthHeightExact($openwave,$model); if($ret!==false) return $ret; } else if(preg_match("/^Mozilla\\/5\\.0 \\(SymbianOS\\/[^;]+; U; Series\\d+\\/\\S+ ([^\\/\\s]+)\\/(\\S*) Profile\\/MIDP-\\d+\\.\\d+ Configuration\\/CLDC-\\d+\\.\\d+[;\\s]*\\) AppleWebKit\\//",$ua,$matches)){ // CLDC Safari $model=$matches[1]; $ret=searchWidthHeightExact($cldc,$model); if($ret!==false) return $ret; } else if(preg_match("/^([^\\/\\s]+)(?:\\/(\\S*))?.*? [Pp]rofile\\/MIDP-\\d+\\.\\d+ [Cc]onfiguration\\/CLDC-\\d+\\.\\d+(?= |$)/",$ua,$matches) && strpos($ua,"Mozilla/")==false){ // CLDC $model=$matches[1]; $ret=searchWidthHeightExact($cldc,$model); if($ret!==false) return $ret; } else if(preg_match("/^([^\\/\\s]+)(?:\\/(\\S*))?.*? MIDP-\\d+\\.\\d+\\/CLDC-\\d+\\.\\d+(?= |$)/",$ua,$matches) && strpos($ua,"Mozilla/")==false){ // CLDC $model=$matches[1]; $ret=searchWidthHeightExact($cldc,$model); if($ret!==false) return $ret; } else if( preg_match("/^Mozilla\\/4\\.0\\s+\\(jig browser[^;]+; ([\\w\\+]+); \\d+\\)/",$ua,$matches) || preg_match("/^Mozilla\\/4\\.0\\s+\\(jig browser[^;]+; [\\d\\.]+; ([\\w\\+]+)\\)/",$ua,$matches)){ // Docomo jig browser $model=$matches[1]; for($i=0;$i100 && $height>100){ return array($width,$height); } } for($i=0;$i