`

UTF-8编码问题编码长度问题

    博客分类:
  • PHP
阅读更多
UTF-8编码问题编码长度问题


UTF-8经常被用于文本文件和网络传输,因为不少这类场合还停留在ANSI时代,需要向纯ASCII兼容。UTF-8是UNICODE的一种变长字符编码 ,长度在1至6字节。这里注意一下,UTF-8曾经是6字节,现在是4字节, 两者都对。 但如果你看到介绍UTF-8的文章说是6字节,基本可以判断这是比较早的文章。在 内容只是ASCII的0X00~0X7F时,UTF-8与ASCII或各种ANSI编码(如GB,JISKSC,ISO-8859-1)的ASCII部分 完全兼容,也是用1字节的低7位表示。这就保证文本编辑器打开的UTF-8格式文档中,即使扩展字符无法显示,但ASCII部分肯定得以顺利解读。这点对 于还需要假定是各种ANSI编码的场合非常有用,比如HTML,前面的纯ASCII部分一直到META标记,然后可以确定随后的编码,而此时UTF-16 则不能正常工作。UTF-8采用如下所示的二进制方式来表示31位UCS-4,X表示有效位:
1字节 0XXXXXXX
2字节 110XXXXX 10XXXXXX
3字节 1110XXXX 10XXXXXX 10XXXXXX
4字节 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
5字节 111110XX 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX
6字节 1111110X 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX
从上可以看得出,如果处在第一字节的引导字节最高位为0,则是一字节。否则看前导1的个数,来确定是几个字节长。前导1与有效位之间有0相隔,也可以通过首字节的值范围来确定字节数。
1字节 0  ~127
2字节 192~223
3字节 224~239
4字节 240~247
5字节 248~251
6字节 252~253
随后的字节每个都以10为前导位,取值范围则在128~191之间。可以立即得知一个字节是否为后续字节,因为引导字节的引导位不是00、01就是11,不会是10。

截取8个字符:
字符串:stefan²º¹³
字节数:14
字符数:10
01110011
01110100
01100101
01100110
01100001
01101110
11000010
10110010
11000010
10111010
11000010
10111001
11000010
10110011

错误的:
字符串:stefan�0
字节数:10
字符数:8
01110011
01110100
01100101
01100110
01100001
01101110
11101111
10111111
10111101
00110000

正确的:
字符串:stefan²º
字节数:10
字符数:8
01110011
01110100
01100101
01100110
01100001
01101110
11000010
10110010
11000010
10111010


涉及到相关代码:
mb_internal_encoding("UTF-8");

$t = "stefan²º¹³";
$t = "绝望的奥特曼绝望的奥特曼";
//$t = "stefan�0";

//$t = mb_substr($t, 0, 8);
$t = my_substr($t, 2, 8);
echo "字符串:" . $t . "\n";
echo "字节数:" . strlen($t) . "\n";
echo "字符数:" . mb_strlen($t) . "\n";

$len = strlen($t);
for($i=0;$i<$len;$i++)
{
    $bin = decbin(ord($t[$i]));
    for($j=8;$j>strlen($bin);$j--)
    {
        echo '0';
    }
    echo $bin . "\n";
}

//自定义utf8截取函数
function my_substr($str, $start, $len)
{
    $cur_len = 0;
    $sub_len = 0;
    $new_str = '';
    $str_len = strlen($str);
    for($i=0;$i<$str_len;)
    {
        $dec = ord($str[$i]);
        $byte_len = 1;
        if($dec<=127)
        {
            $byte_len = 1;
        }
        else if($dec>=192 && $dec<=223)
        {
            $byte_len = 2;
        }
        else if($dec>=224 && $dec<=239)
        {
            $byte_len = 3;
        }
        else if($dec>=240 && $dec<=247)
        {
            $byte_len = 4;
        }
        else if($dec>=248 && $dec<=251)
        {
            $byte_len = 5;
        }
        else if($dec>=252 && $dec<=253)
        {
            $byte_len = 6;
        }
        else
        {
            // 异常
            $i++;
            continue;
        }

        for($j=$byte_len;$j>0;$j--)
        {
            if($cur_len>=$start)
            {
                $new_str .= $str[$i];
            }
            $i++;
        }

        if($cur_len>=$start)
        {
            $sub_len++;
        }
        $cur_len++;
        if($sub_len>=$len)
        {
            break;
        }
    }

    return $new_str;
}
分享到:
评论

相关推荐

    UTF-8编码转换器

    UTF-8编码是一种广泛使用的字符编码标准,它在信息技术领域起着至关重要的作用。这个“UTF-8编码转换器”工具旨在帮助用户方便地将文本数据从其他编码格式转换为UTF-8,确保数据在不同系统和平台之间的兼容性。 在...

    UTF-8 汉字码表

    ### UTF-8编码详解与汉字码表解析 #### UTF-8编码原理 UTF-8(Unicode Transformation Format - 8 bits)是一种变长字符编码,由Ken Thompson于1992年设计,旨在解决多语言环境下字符编码兼容性问题。其核心优势...

    UTF-8 编码转换工具

    总之,UTF-8编码转换工具是一个实用的工具,可以帮助用户在处理各种编码问题时进行转换。了解UTF-8编码的工作原理和应用场景,对于从事IT工作的人来说是必不可少的基础知识。在实际工作中,无论是开发网页、编写代码...

    UTF-8汉字码表.txt

    ### UTF-8编码详解 #### 一、简介 在计算机科学领域中,字符编码是将字符映射到二进制数字的一种方式。其中,UTF-8(8位通用转换格式)是一种可变长度的字符编码,它兼容ASCII,并且能够表示Unicode标准中的所有...

    UTF-8 Unicode GBK GB2312 编码之间的区别和联系

    - 对于含有大量英文字符的网站或论坛,建议使用UTF-8编码,因为它更节省空间且具有更好的国际通用性。 - 对于需要支持GBK编码的插件或软件,在没有UTF-8支持的情况下,可能需要使用GBK编码。 #### 八、总结 UTF-8...

    汉字字符编码(utf-8 unicode gb2312)

    - **UTF-8中文字符表.txt**:这个文件可能包含了使用UTF-8编码的所有中文字符,每个字符会以UTF-8编码的形式展示,通常用于验证程序对UTF-8编码的支持或进行字符编码教学。 - **unicode 汉字表.txt**:此文件很可能...

    Unicode字符的UTF-8、UTF-16、UTF-32编码方式[总结].pdf

    Unicode 字符的 UTF-8、UTF-16、UTF-32 编码方式 Unicode 字符集是计算机上使用的一种字符编码,它为每种语言中的每个字符设定了统一并且唯一的二进制代码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode...

    utf-8 ansi 字符互转 工具

    总结来说,理解和掌握UTF-8与ANSI字符编码的差异,以及如何进行转换,对于解决跨平台、多语言环境下的文本处理问题至关重要。在日常工作中,我们可以利用各种工具和编程手段,灵活应对不同编码格式带来的挑战。在...

    易语言判断UTF-8字符

    UTF-8编码的特点是不同的字符由不同数量的字节表示,从1字节到4字节不等,且每个字节的最高位都有特定的值来标识这是一个UTF-8编码的字符。 在易语言中,使用`IsTextUTF8`函数通常涉及以下几个关键知识点: 1. **...

    c++ UTF-8 UTF-16转换

    在编程领域,尤其是在涉及到字符编码的时候,理解和操作UTF-8和UTF-16之间的转换是一项基本技能。UTF-8和UTF-16是两种广泛使用的Unicode编码格式,它们各自有其特性和应用场景。本文将深入探讨如何利用C++来实现这两...

    C++使用WideCharToMultiByte函数生成UTF-8编码文件的方法

    在C++编程中,将Unicode字符串转换为UTF-8编码并保存到文件是常见的操作,尤其是在处理跨平台的文本数据时。WideCharToMultiByte函数是Windows API提供的一种方法,用于将Unicode字符串转换为特定的多字节字符集,...

    通过系统api转化UTF-8编码的VB模块源码

    使用这些API转换函数可以有效地解决这个问题,使得VB能够处理UTF-8编码的文本,从而更好地适应全球化开发需求。 总之,通过VB模块中的系统API,我们可以实现对UTF-8编码和其他编码的转换,这对于处理多语言环境下的...

    通过javascript进行UTF-8编码的实现方法

    因为英文字符和英文字符的Unicode码值小于128,所以它们在UTF-8编码中占用的字节长度与Unicode相同。但对于其他语言中的字符,如汉字,Unicode码值通常在2048到65535之间,因此在UTF-8中需要三个字节来表示。 具体...

    JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换

    - **Unicode到UTF-8**: 同样以"a 中文"为例,转换为UTF-8编码后,字节数组为`0x61 0xE4 0xB8 0xAD 0xE6 0x96 0x87`。 - **UTF-8到Unicode**: 反向转换后,结果依然是"a 中文"。 ##### 3. Unicode与ISO-8859-1 - **...

    GB2312转UTF-8(C代码)

    UTF-8的一个显著特点是兼容ASCII编码,对于ASCII字符,UTF-8编码与ASCII编码完全相同,仅用一个字节表示。对于非ASCII字符,UTF-8使用1到4个字节来表示,这样设计使得在多数英文为主的系统中,可以有效利用存储空间...

    UNICODE与UTF-8转换

    **二、UTF-8编码** UTF-8是一种变长的Unicode转换格式,它将UNICODE码点转换为可变长度的字节序列。UTF-8的优势在于其对ASCII字符的兼容性:英文和其他使用ASCII字符的语言,如大部分编程语言,只需要1个字节表示,...

    js gb2312和utf-8互转

    根据提供的文件信息,本文将详细...通过上述步骤,我们可以在JavaScript中实现GB2312与UTF-8编码之间的互相转换,这对于处理不同编码格式的数据非常重要,特别是在多语言环境下,能够有效避免乱码问题,提高用户体验。

    utf-8文件非常好用

    UTF-8编码,全称为UCS Transformation Format-8,是一种针对Unicode字符集的可变长度字符编码,由互联网工程任务组(IETF)于1993年提出。它集灵活性与效率于一身,能够适应各种文字系统的需求。UTF-8使用1至4个字节...

    多字节与UTF-8、Unicode之间的转换

    - 再通过`WideCharToMultiByte`函数将宽字符字符串转换为UTF-8编码的字符序列。 2. **UTF8ToMB** 该函数实现了从UTF-8编码转换回多字节编码的过程。其流程与上述过程相反: - 先使用`MultiByteToWideChar`将...

    字符集Unicode与UTF-8之间的转换

    这段代码将Unicode字符“你”转换为UTF-8编码的字节序列。 Unicode和UTF-8都是重要的字符集和编码方式,了解它们之间的转换非常重要。通过本文的介绍,读者可以更好地理解Unicode和UTF-8的区别和转换方法,并在实际...

Global site tag (gtag.js) - Google Analytics