• 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']); }
  • 相关阅读:
    UVA11584 划分成回文串
    UVA1220Party at Hali-Bula(树的最大独立集 + 唯一性判断)
    BUAA1389愤怒的DZY(最大值最小化)
    九度1502 最大值最小化问题
    App(4.25)
    App(4.24)
    App(4.23)
    App(4.22)
    学习进度条(八)
    App(4.21)
  • 原文地址:https://www.cnblogs.com/dreamyoung/p/isutf8.html
Copyright © 2020-2023  润新知