PHP判斷字符串所屬編碼:ASCII、GB2312、GBK、UTF-8、ISO-8859-1


ASCII: ASCII的編碼范圍為0-127(十六進制:0x00-0x7F),判斷函數:

function isasciistr($str){
    for($i=0;$i<strlen($str);$i++){
        if(ord(substr($str,$i,1))>0x7F) return false;
    }
    return true;
}

 

 

ISO-8859-1:也稱Latin1。編碼范圍是0-255(0x00-0xFF)。0x00-0x7F之間完全和ASCII一致,0x80-0x9F之間是控制字符,0xA0-0xFF之間是文字符號,判斷函數:

 因為ISO-8859-1的范圍中包含了0xC2-0xDF以及0x80-0xBF,而UTF-8的兩、三、四字節中都可能出現在這些范圍。所以,有可能將ISO-8859-1錯判斷為UTF-8,一般需要指定順序,在兩者都符合的情況下,順序優先。

function islatin1str($str,$order=''){
    if(empty($order)) $order = array('ASCII','UTF-8','ISO-8859-1');
    
    $cs = ['ASCII'=>'isasciistr','GB2312'=>'isgb2312str','GBK'=>'isgbkstr','UTF-8'=>'isutf8str'];
    
    $flags = [];
    $charset = false;
    $other = [];
    for($i=0;$i<count($order);$i++){
        $ofun = NULL;
        if($order[$i]!='ISO-8859-1' && $order[$i]!='WINDOWS-1252'){
            $ofun = $cs[$order[$i]];
            if(!empty($ofun)){
                $charset = $order[$i]=='UTF-8' ? call_user_func_array("$ofun",array($str,true)): call_user_func("$ofun",$str);
                if($charset){
                    $other[] = $order[$i];
                }
            }
            
        }
    }
    
    $flag = true;
    $N = count($other);
    if($N>0){
        for($k=0;$k<$N;$k++){
            if(array_search('ISO-8859-1',$order)!==false){
                if(array_search($other[$k],$order)<array_search('ISO-8859-1',$order)){
                    return false;
                }
            }
        }
    }
    
    return true;
    
}

判斷是否ISO-8859-1的函數中利用到了其它幾個判斷函數(見下邊),分別是isasciistr()、isgb2312str()、isgbkstr()、isutf8str()。

 

GB2312:簡體中文編碼,范圍是0xA1A1-0xFEFE(漢字所在編碼范圍為B0A1-F7FE)。判斷函數如下:

function isgb2312str($str){
    $len = strlen($str);
    for($i=0;$i<$len;$i++){
        $c1 = substr($str,$i,1);
        if(ord($c1)<=0x7F) continue;
        $flag1 = ord($c1)>=0xA1 && ord($c1)<=0xFE;
        if(!$flag1 || $i==$len-1) return false;
        $c2 = substr($str,$i+1,1);
        $flag2 = ord($c2)>=0xA1 || ord($c2)<=0xFE;
        if(!$flag2) return false;
        $i++;
    }
    
    return true;
}

 

 

GBK:在GB2312基礎上擴展的編碼,范圍是0x8140-0xFEFE。判斷函數如下:

function isgbkstr($str){
    $len = strlen($str);
    for($i=0;$i<$len;$i++){
        $c1 = substr($str,$i,1);
        if(ord($c1)<=0x7F) continue;
        $flag1 = ord($c1)>=0x81 && ord($c1)<=0xFE;
        if(!$flag1 || $i==$len-1) return false;
        $c2 = substr($str,$i+1,1);
        $flag2 = ord($c2)>=0x81 || ord($c2)<=0xFE;
        if(!$flag2) return false;
        $i++;
    }
    
    return true;
}

 

 

UTF-8:這是可變長(一字節,兩字節,三字節,四字節,五字節,六字節)的編碼。通常只處理到四個字節的編碼,由於部分編碼范圍可能與GBK非漢字部分重疊(網上很多版本都不太准確),需要處理一下,判斷如下:

function isutf8str($str,$utf8all2bits=false){
    $bit2 = true;
    $bit3 = false;
    $bit4 = false;
    $allCN = array();
    $len = strlen($str);
    for($i=0;$i<$len;$i++){
        $c1 = substr($str,$i,1);
        if(ord($c1)<=0x7F) continue;
        if(ord($c1)>=0xFF) return false;
        $flag1_2 = ord($c1)>=0xc0 && ord($c1)<=0xdf;
        $flag1_3 = ord($c1)>=0xe0 && ord($c1)<=0xef;
        $flag1_4 = ord($c1)>=0xf0 && ord($c1)<=0xf7; 
        if(!($flag1_2 || $flag1_3 || $flag1_4) || $i==$len-1) return false;
        $c2 = substr($str,$i+1,1);
        
        $flag2 = ord($c2)>=0x80 && ord($c2)<=0xbf;
        if(!$flag2) return false;
        if($flag1_2){
            $bit2 = true;
            $allCN[] = (ord($c1)>=0xB0 && ord($c1)<=0xF7 && ord($c2)>=0xA1 && ord($c2)<=0xFE) ? 1 : 0;
            
            if($i==$len-2) {

if($bit3 || $bit4) return true;
$N = count($allCN); if($N>0){ for($n=0;$n<$N;$n++){ if($allCN[$n]!=1){ return true; } } } return $utf8all2bits; } $i=$i+1; }else{ if($i==$len-2) return false; $c3 = substr($str,$i+2,1); $flag3 = ord($c3)>=0x80 && ord($c3)<=0xbf; if(!$flag3) return false; if($flag1_3){ $bit3 = true; if($bit2 || $bit4 || $i==$len-3) return true; $i=$i+2; }else{ $bit4 = true; if($i==$len-3) return false; $c4 = substr($str,$i+3,1); $flag4 = ord($c4)>=0x80 && ord($c4)<=0xbf; if(!$flag4) return false; if($bit2 || $bit3 || $i==$len-4) return true; $i=$i+3; } } } return true; }

 

 

 

以上各種編碼也可以使用mb_detect_encoding()來處理,不過需要注意順序:

function isasciistr($str){
    return in_array(mb_detect_encoding($str,array('ASCII','GB2312','GBK','UTF-8','ISO-8859-1')),['ASCII','ISO-646']);
}
function islatin1str($str){ return in_array(mb_detect_encoding($str,array('ASCII','GB2312','GBK','UTF-8','ISO-8859-1')),['Latin1','ISO-8859-1']); }
function isgb2312str($str){ return in_array(mb_detect_encoding($str,array('ASCII','GB2312','GBK','UTF-8','ISO-8859-1')),['GB2312','EUC-CN']); }
function isgbkstr($str){ return in_array(mb_detect_encoding($str,array('ASCII','GB2312','GBK','UTF-8','ISO-8859-1')),['GBK','CP936']); }
function isut8str($str){ return in_array(mb_detect_encoding($str,array('ASCII','GB2312','GBK','UTF-8','ISO-8859-1')),['UTF-8']); }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM