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. js多张图片合成一张图,canvas(海报图,将二维码和背景图合并) -----vue

    思路:vue中图片合并 首先准备好要合并的背景图,和请求后得到的二维码, canvas画图,将两张背景图和一张二维码用canvas画出来, 将canvas再转为img 注意canvas和图片的清晰图和 ...

  2. kafka语句示例

    1.从http://kafka.apache.org/下载kafka安装包:2.tar zxvf kafka_2.8.0.tar.gz,修改配置文件conf/server.properties:bro ...

  3. Qt - 基于UDP的网络编程

    UDP(用户数据报协议 User Data Protocol) 轻量级.不可靠.面向数据报.无连接  的传输层协议. 适用情况: 网络数据大多为短消息: 拥有大量客户端: 对数据安全无特殊要求: 网络 ...

  4. [转帖]黑客通过 Rootkit 恶意软件感染超 5 万台 MS-SQL 和 PHPMyAdmin 服务器

    黑客通过 Rootkit 恶意软件感染超 5 万台 MS-SQL 和 PHPMyAdmin 服务器 https://www.cnbeta.com/articles/tech/852141.htm 病毒 ...

  5. Python进阶编程 类的成员

    类的成员 class A: company_name='老男孩' #静态变量 __iphone='1515151' #私有静态变量 def __init__(self,name,age): #特殊方法 ...

  6. 细说Python的lambda函数用法,建议收藏

    细说Python的lambda函数用法,建议收藏 在Python中有两种函数,一种是def定义的函数,另一种是lambda函数,也就是大家常说的匿名函数.今天我就和大家聊聊lambda函数,在Pyth ...

  7. Java编程思想读书笔记 第十章 内部类

    非静态内部类作用: 最基本的作用:名字隐藏和组织代码 用例:内部类不访问外部类的元素时可以直接new.(bad style!) 用例:通过外部类的非静态方法返回内部类的引用,这样隐含了内部类对象和其对 ...

  8. 使用python的kazoo模块连接zookeeper实现最基本的增删改查

    kazoo的官方文档地址:https://kazoo.readthedocs.io/en/latest/index.html #!/usr/bin/env python # -*- coding: u ...

  9. Kibana多用户创建及角色权限控制

    1 介绍 ELK日志管理属于基础设施平台,接入多个应用系统是正常现象,如果接入多个系统的索引文件没有进行权限划分,那么很大程度会出现索引文件误处理现象,为了避免这种情况发生,多用户及权限设置必不可少. ...

  10. [.net core]8.中间件的概念

    假设我们的中间件是这样的(可以自由排列, 扩展自定义中间件) logging负责记录请求/响应 staticFiles 负责响应 静态文件 MVC 负责响应 视图 当.net core web app ...