ASCII、Unicode和UTF-8编码的区别;中英文混合截取

摘要总结:

ASCII编码是128个字符

中国把汉字编入GB2312,Shift_JIS/Euc-kr各国标准.....

Unicode是为了解决各国乱码的,但浪费存储空间

UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6字节,英文字母是1字节,汉字通常是3字节,生僻字符是4-6字节


简单归纳:

编码 大小 支持语言
ASCII 1个字节 英文
Unicode 2个字节(生僻字4个) 所有语言
UTF-8 1-6个字节,英文字母1个字节,汉字3个字节,生僻字4-6个字节 所有语言
具体解释:
最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。
UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,

所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。



理论解释:

1、ASCII码
在计算机内部,所有的信息最终都表示为一个二进制的字符串。
一个字节一共有256种不同的状态,从0000000到11111111。
上世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定,称为ASCII码。
ASCII码一共规定了128个字符的编码。这128个符号,只占用了一个字节的后面7位,最前面的1位统一规定为0。
2、非ASCII编码
扩展ASCII码在保留原始的7位的基础上,使用了最前的一位。
不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。
3、Unicode
正如上一节所说,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。
可以想象,如果有一种编码,将世界上所有的符号都纳入其中。
每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。
这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。
Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。
每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字"严"。
Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
出现了两个严重的问题,
第一个问题是,如何才能区别Unicode和ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?
第二个问题是,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍。
4、UTF-8
UTF-8就是在互联网上使用最广的一种Unicode的实现方式。UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。
它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

5、Unicode与UTF-8之间的转换
1)ANSI是默认的编码方式。
    对于英文文件是ASCII编码,对于简体中文文件是GB2312编码。(繁体中文版会采用Big5码)
2)Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。little endian格式
3)Unicode big endian编码格式
4)UTF-8编码方式

首先我们要明确 UTF-8(8-bit Unicode Transformation Format)是在统一码(Unicode)基础上细化并优化后的一种长度可变的字符编码方式,它是实现 Unicode 的方式之一,除了 UTF-8,还有UTF-16,UTF-32 等都可以实现 Unicode,但是 UTF-8 相对而言是用的最为广泛的。
UTF-8 可以使用1到4个字节来表示字符,它通过自身的规则能够灵活地变化长度来存储 Unicode 字符。
Unicode是两个字节吗?
Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体存储为什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-16和UTF-8。





   = $sLen )
    {
        return $str;
    }
 
    //判断使用什么编码,默认为utf-8
    if ( strtolower($charset) == "utf-8" )
    {
        $len_step = 3; //如果是utf-8编码,则中文字符长度为3  
    }else{
        $len_step = 2; //如果是gb2312或big5编码,则中文字符长度为2
    } 

    //执行截取操作
    $len_i = 0; 
    //初始化计数当前已截取的字符串个数,此值为字符串的个数值(非字节数)
    $substr_len = 0; //初始化应该要截取的总字节数

    for( $i=0; $i < $sLen; $i++ )
    {
        if ( $len_i >= $len ) break; //总截取$len个字符串后,停止循环
        //判断,如果是中文字符串,则当前总字节数加上相应编码的中文字符长度
        if( ord(substr($str,$i,1)) > 0xa0 )
        {
            $i += $len_step - 1;
            $substr_len += $len_step;
        }else{ //否则,为英文字符,加1个字节
            $substr_len ++;
        }
        $len_i ++;
    }
    $result_str = substr($str,0,$substr_len );
    return $result_str;
}


// 调用示例

$str = "空格 也算一个字符"; 
echo "截取后的字符串:".left($str,14); 
//ord()是返回ASCII值;在ASCII中,0xa0表示汉字的开始
?>



参考链接1:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
                    https://my.oschina.net/darionyaphet/blog/221124
            http://blog.csdn.net/u012223913/article/details/51772610

参考链接2:http://blog.csdn.net/u012223913/article/details/51772610

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页