0x00 前言

第一次遇见字符串这个概念是在学 C 语言的时候,那时候觉得字符串也没有什么难的,不就是一个以 \0 结尾的 char 数组而已咯。后来在学习 PHP 的过程中也同样保持这个观念,不过在字符串还是纯英文的时候还是没什么问题的,但后面遇到要处理中文的时候就事故频发,然后搜索结果里的字符集字符编码多字节字符串二进制安全各种概念搞得一头雾水,虽然最后的搜索结果都附有了解决方案但我还是觉得对于相关的知识需要理解和总结。

0x01 字符集

字符集(全称是编码字符集)是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集都可以用「一张或多张二维表」表示,比如:ASCII 是很常见的一个字符集,一提起它我们应该都能想到下面这张图。我们可以看见每一个字符都对应有一个二进制编码

因为ASCII 字符集上的编码和字符编码是一样的,然后很多刚学习的人就把字符集和字符编码给弄混淆了。但是实际上字符集和字符编码是不同的概念

0x02 字符编码

由于历史原因,在早期字符集其实和字符编码是同义的,因为字符集的编码就是对应字符实际储存的值,直到 Unicode 的出现,因为 Unicode 有好几种不同的字符编码,比如:UTF-8UFF-16UTF-32。然后字符编码的概念就出来了,字符编码是字符集和实际存储数值之间的转换关系,也就是说字符编码是定义在字符集上的映射规则。然后我就开始有点头晕了/(ㄒoㄒ)/~~,字符编码 UTF-8 和字符集 Unicode 到底是什么关系?

实际上我们可以说UTF-8 是 Unicode 的一种实现方式云服务器Window Server 2012R系统安装MySQL的详细教程

我们可以查到在 Unicode 码表中,「国」字对应的十六进制编码是 0x56FD 但是如果我们新建一个文本文件,输入一个「国」字并用 UTF-8 的字符编码储存,然后以十六进制的方式查看该文件,我们会发现储存的并不是 0x56FD 而是 0xE59BBD。因为字符集的编码通过某种规则转换为了实际存储的数据,这里的某种规则即是字符编码。下面一图可以看出字符集和字符编码的不同。

既然字符集已经有编码了(而且很多字符集的字符编码和字符集上的编码一样),那为何要多此一举搞个字符编码出来?因为如果直接采用字符集上的编码,那么像 Unicode 之类的字符集,它的每个字符都需要三个字节储存,而对于一些常见的字符(比如:英文字母)来说用三个字节储存无疑是很浪费空间的。而通过 UTF-8 字符编码便可以将常见的字符采用较少的字节编码,而不常用的字符就采用较多的字节编码,达到节约储存空间的目的。

0x03 多字节字符串

PHP 在处理非英文的字符串时,部分字符串相关的函数可能会经常出现问题,因为 PHP 中处理字符串的函数默认假设所有字符都是 8 位字符,占用一个字节。而中文至少要用两个或三个字节储存(使用 UTF-8 编码),所以经常会出错。比如 strlen 函数在测试中文字符串时得到的是字节长度而不字符长度,所以我们应该利用 mbstring 拓展 提供的多字节字符串函数进行处理。

0x04 二进制安全

在浏览字符串处理函数的过程中我们常常会看到一个词「二进制安全」,听着感觉很高大上的样子然后网上对它的解释如下:

二进制安全是一个主要用来处理字符串操作的编程术语。二进制安全功能本质上是把输入当作一个没有任何特殊的原生流,其在操作上应包含一个字符所能有的256种可能的值(假设为8为字符)。

听着有点似懂非懂的样子,但和 C 语言的字符串作对比之后就比较明白了。

C 字符串中的字符必须符合某种编码(比如 ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾 ——这些限制使得 C 字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据。

也就是说在二进制安全的函数操作里 \0 并不会看做字符串的结尾,字符串中所有的数据都没有特殊的含义。所以 PHP 的 strlen 函数能获取包含空字符的字符串长度,而 C 语言却不行。当然 PHP 里也有非二进制安全的函数,所以在使用某些函数前还是要注意函数是否是二进制安全的。如下例:

<?php
$str1 = "good";
$str2 = "good\0bad";
var_dump(strcoll($str1, $str2));
// 非二进制安全,输出 0
var_dump(strcmp($str1, $str2));
// 二进制安全,输出 -4

  

写这篇文章的时候真的觉得很难写( ⊙ o ⊙ )啊!感觉自己还是说的不清不楚的样子,还没有网上的资料讲得好。但进行一下总结起码能够加强记忆吧/(ㄒoㄒ)/~~。有错的地方希望有人能够提出来(但我觉得应该都不会有人来看我的博客的233,更不会有评论)。0x05 总结

0x06 参考资料

十分钟搞清字符集和字符编码

字符集和字符编码

字符,字符集,字符编码解惑

PHP 的二进制安全

文章转自:https://www.0php.net/posts/PHP-字符串相关常识.html

PHP 字符串相关常识的更多相关文章

  1. 常用linux 命令 -字符串相关

    参考网络文章,个人工作总结 题记:一般对字符串的操作有以下几种:求长度,截取字符串,拼接字符串,找字符串中某个字符的索引 1 expr 命令 1.1 定义 man 手册 Print the value ...

  2. 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树

    另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...

  3. python中跟字符串相关的一些操作

    公司让用python自动生成代码,以前没看过python.所以匆匆的看了两天python就连猜带蒙就上马开干了..因此好多操作可能看的时候看懂了,用的时候知道有这么个东西,具体用法就忘记了..用到了就 ...

  4. IP相关常识

    IP相关常识 一.  IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机.网络ID用来标识计算机所处的网段:主机ID用来标识计算机在网段 ...

  5. ES6字符串相关扩展

    变量的解构赋值 // 数组的解构赋值 let [a,b,c] = [1,2,3]; //1,2,3 let [a,b,c] = [,123,]; //undefined 123 undefined l ...

  6. Java数据结构和算法总结-字符串相关高频面试题算法

    前言:周末闲来无事,看了看字符串相关算法的讲解视频,收货颇丰,跟着视频讲解简单做了一下笔记,方便以后翻阅复习同时也很乐意分享给大家.什么字符串在算法中有多重要之类的大路边上的客套话就不多说了,直接上笔 ...

  7. PHP基础系列(一) PHP字符串相关的函数分类整理

    PHP提供了非常丰富的自带函数,有人说PHP是一个大的函数库,在某种程度上我是非常认同这种观点的,这个也是PHP非常容易上手的原因之一.在使用PHP编程的时候,需要实现某一功能的时候,如果说php自带 ...

  8. python字符串、字符串处理函数及字符串相关操作

    python字符串.字符串处理函数及字符串相关操作 字符串介绍 python字符串表示 Python除处理数字外还可以处理字符串,字符串用单撇号或双撇号包裹: >>> 'spam e ...

  9. java常用类详细介绍及总结:字符串相关类、日期时间API、比较器接口、System、Math、BigInteger与BigDecimal

    一.字符串相关的类 1.String及常用方法 1.1 String的特性 String:字符串,使用一对""引起来表示. String声明为final的,不可被继承 String ...

随机推荐

  1. python 三元运算、列表推倒式、字典推倒式、生成器生成式

    1.三元运算 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(res) 2.列表推倒式 #1.示例 egg_ ...

  2. ${pagecontext.request.contextpath}绝对路径理解

    ${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> .也就是取出部署的应用程序 ...

  3. Kali安装在U盘+使用aircrack-ng套件

    因为: Kali Linux 自带aircrack-ng 虚拟机VMware不能用笔记本内置网卡,需要另外买一个无线网卡,然而并不想买 不想给笔记本重装Kali Linux系统 有闲置的32GU盘 所 ...

  4. tf-图像预处理

    tensorflow 中自带了很多图像处理的方法,基本都在 tf.image 模块中,虽然不如 opencv 强大,但也比较常用,这里做个记录. 图像编解码 1. 用 tf 的方法读取图片后,都需要进 ...

  5. 严重报错: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis

    其实可能是你的jar文件没有同步发布到自己项目的lib目录中(如果你是用Maven进行构建的话) 可以试试 下面的办法 项目点击右键 点击 Properties 选择Deployment Assemb ...

  6. Balloon Robot ZOJ - 3981

    大意: n个参赛队, m个座位, 一共交了p次题, 一个机器人每秒钟会从位置$i$走到$i+1$, 若在$m$直接走到$1$, 当走到一个队伍就给该队应得的气球. 对于每道题, 假设交题时间$t_a$ ...

  7. 一分钟理解sdk

    SDK 外语:Software Development Kit 中文:软件开发工具包 含义:一般都是一些软件工程师为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件时的开发工具的集合. 通俗: ...

  8. 32、出任爬虫公司CEO(爬取职友网招聘信息)

    职友集,搜索到全国上百家招聘网站的最新职位.   https://www.jobui.com/rank/company/   打开网址后,你会发现:这是职友集网站的地区企业排行榜,里面含有     本 ...

  9. Centos7 配置LAMP+fastcgi(Centos7.2+php7.0+mariadb+httpd)

    环境:阿里云centos7.3 一.安装并配置数据库 1.安装数据库 #yum install mariadb-server  mariadb -y 2.启动服务并设置开机自启 # systemctl ...

  10. jQuery中outerWidth()方法

    截图自:菜鸟教程https://www.runoob.com/jquery/html-outerwidth.html