常见编码及乱码的处理

  • 常见编码及乱码的处理
    • 前言
    • 一、字符集与编码
      • 1、字符集简介
      • 2、ASCII编码
      • 3、Latin1字符集
      • 4、UTF-8编码
      • 5、字符集兼容性
      • 6、文件编码从哪看?
      • ASCII码表
    • 二、乱码
      • 1、文件乱码
      • 2、HTML乱码
      • 3、JSP乱码
      • 4、GET,POST请求乱码
        • 1)get提交
        • 2)post提交
      • 5、URL包含特殊字符
      • 6、数据库乱码
        • 1、MySQL环境变量
        • 2、MySQL字符集
        • 3、MySQL字符集的设置
        • 4、MySQL字符集的转换过程
        • 5、MySQL乱码产生的原因
        • 6、编码无损转换

常见编码及乱码的处理

本文解决的问题

  • 编码是什么
  • 字符是什么
  • 字符集是什么
  • 编码用在哪
  • 我们常出现的错误(乱码)
  • 怎么正确的使用编码

前言

我们日常接触到的文件分ASCII是“美国信息交换标准编码”的英文字头缩写,可称之为“美标”。美标规定了用从0到127的128个数字来代表信息的规范编码,其中包括33个控制码,一个空格码,和94个形象码。形象码中包括了英文大小写字母,阿拉伯数字,标点符号等。我们平时阅读的英文电脑文本,就是以形象码的方式传递和存储的。美标是国际上大部分大小电脑的通用编码。

然而电脑中的一个字符大都是用一个八位数的二进制数字表示。这样就有256个不同的数值,可以用来表示256个不同的字符。由于美标只规定了128个编码,剩下的另外128个数码没有规范,各家用法不一。另外美标中的33个控制码,各厂家用法也不尽一致。这样我们在不同电脑间交换文件的时候,就有必要区分两类不同的文件。第一类文件中每一个字都是美标形象码或空格码。这类文件称为“美标文本文件”(ASCII Text Files),或略为“文本文件”,通常可在不同电脑系统间直接交换。第二类文件,也就是含有控制码或非美标码的文件,通常不能在不同电脑系统间直接交换。这类文件有一个通称,叫“二进制文件”(Binary Files)。

本文讨论的内容只在可读文本即ASCII系列

文章目录

  • 常见编码及乱码的处理
    • 前言
    • 一、字符集与编码
      • 1、字符集简介
      • 2、ASCII编码
      • 3、Latin1字符集
      • 4、UTF-8编码
      • 5、字符集兼容性
      • 6、文件编码从哪看?
      • ASCII码表
    • 二、乱码
      • 1、文件乱码
      • 2、HTML乱码
      • 3、JSP乱码
      • 4、GET,POST请求乱码
        • 1)get提交
        • 2)post提交
      • 5、URL包含特殊字符
      • 6、数据库乱码
        • 1、MySQL环境变量
        • 2、MySQL字符集
        • 3、MySQL字符集的设置
        • 4、MySQL字符集的转换过程
        • 5、MySQL乱码产生的原因
        • 6、编码无损转换

一、字符集与编码

1、字符集简介

**字符(Character)**是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
**字符集(Character set)**是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。

**字符编码(Character encoding)**是把字符集中的某个字符编码为指定字符集中字符,以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成ASCII,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示。

**字符序 (collation)**是指同一个字符集内字符之间的比较规则。只有确定字符序后,才能在一个字符集上定义什么是等价的字符,以及字符之间的大小关系。一个字符可以包含多种字符序。MySQL字符序命名规则是:以字符序对应的字符集名称开头,以国家名居中(或以general居中),以ci、cs、或bin结尾。以ci结尾的字符序表示大小写不敏感,以cs结尾的字符序表示大小写敏感,以bin结尾的字符序表示按二进制编码值比较。

2、ASCII编码

ASCII既是编码字符集,又是字符编码,ASCII直接将字符在编码字符集中的序号作为字符在计算机中存储从数值。
例如:在ASCII中A字符在表中排第65位,序号是65,而编码后A的数值是0100 0001,即十进制的65的二进制转换结果。

3、Latin1字符集

Latin1字符集在ASCII字符集基础上进行了扩展,仍然使用一个字节表示字符,但启用了高位,扩展了字符集的表示范围。

4、UTF-8编码

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码Unicode字符。
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 如表:
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
因此UTF-8中可以用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去控制位(每字节开头的10等),x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。
实际将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数。 因此基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一个字节的UTF-8编码(7个二进制位)便可以表示。

5、字符集兼容性

对于中文字符来说,UTF-8、GBK、GB2312、BIG5四种编码之间是互不兼容的,直接相互转换会导致乱码;当UTF-8、GBK、GB2312、BIG5四种编码转换为ASCII编码和Latin1编码格式时,每个中文字符会被转换为0x3F,即中文字符’?’。
GB2312支持简体中文,BIG5支持繁体中文,GBK支持简体中文及繁体中文,UTF-8支持几乎所有字符。
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GB2312是GBK的子集,GBK是GB18030的子集。

GB编码标准中,比较常用的是GB2312和GBK两种,GB2312是GBK的一个子集,GB2312编码范围是 0xA1A1 - 0xFEFE ,如果纯粹的 GB2312编码,处理起来是十分简单的,但处理GBK字符集时有些小的提示,先说说GBK编码的标准吧:

GBK 采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。

6、文件编码从哪看?

以notepad++ 为例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6en5xDiL-1574241894791)(https://i.loli.net/2019/11/12/kxESrPKRHlXATBY.png)]

我们打开一个文本文件

一般默认会指定一个正确的编码去读

如果我们以二进制的方式打开文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fksApxjd-1574241894792)(https://i.loli.net/2019/11/12/aTyPWf2QOJcnrAx.png)]

ASCII码表

二进制 十进制 十六进制 缩写 名称/意义
0000 0000 0 0 NUL 空字符(Null)
0000 0001 1 1 SOH 标题开始
0000 0010 2 2 STX 本文开始
0000 0011 3 3 ETX 本文结束
0000 0100 4 4 EOT 传输结束
0000 0101 5 5 ENQ 请求
0000 0110 6 6 ACK 确认回应
0000 0111 7 7 BEL 响铃
0000 1000 8 8 BS 退格
0000 1001 9 9 HT 水平定位符号
0000 1010 10 0A LF 换行键
0000 1011 11 0B VT 垂直定位符号
0000 1100 12 0C FF 换页键
0000 1101 13 0D CR 归位键
0000 1110 14 0E SO 取消变换(Shift out)
0000 1111 15 0F SI 启用变换(Shift in)
0001 0000 16 10 DLE 跳出数据通讯
0001 0001 17 11 DC1 设备控制一(XON 启用软件速度控制)
0001 0010 18 12 DC2 设备控制二
0001 0011 19 13 DC3 设备控制三(XOFF 停用软件速度控制)
0001 0100 20 14 DC4 设备控制四
0001 0101 21 15 NAK 确认失败回应
0001 0110 22 16 SYN 同步用暂停
0001 0111 23 17 ETB 区块传输结束
0001 1000 24 18 CAN 取消
0001 1001 25 19 EM 连接介质中断
0001 1010 26 1A SUB 替换
0001 1011 27 1B ESC 跳出
0001 1100 28 1C FS 文件分割符
0001 1101 29 1D GS 组群分隔符
0001 1110 30 1E RS 记录分隔符
0001 1111 31 1F US 单元分隔符
0111 1111 127 7F DEL 删除
二进制 十进制 十六进制 图形
0010 0000 32 20 (空格)(␠)
0010 0001 33 21 !
0010 0010 34 22 "
0010 0011 35 23 #
0010 0100 36 24 $
0010 0101 37 25 %
0010 0110 38 26 &
0010 0111 39 27
0010 1000 40 28 (
0010 1001 41 29 )
0010 1010 42 2A *
0010 1011 43 2B +
0010 1100 44 2C ,
0010 1101 45 2D -
0010 1110 46 2E .
0010 1111 47 2F /
0011 0000 48 30 0
0011 0001 49 31 1
0011 0010 50 32 2
0011 0011 51 33 3
0011 0100 52 34 4
0011 0101 53 35 5
0011 0110 54 36 6
0011 0111 55 37 7
0011 1000 56 38 8
0011 1001 57 39 9
0011 1010 58 3A :
0011 1011 59 3B ;
0011 1100 60 3C <
0011 1101 61 3D =
0011 1110 62 3E >
0011 1111 63 3F ?
0100 0000 64 40 @
0100 0001 65 41 A
0100 0010 66 42 B
0100 0011 67 43 C
0100 0100 68 44 D
0100 0101 69 45 E
0100 0110 70 46 F
0100 0111 71 47 G
0100 1000 72 48 H
0100 1001 73 49 I
0100 1010 74 4A J
0100 1011 75 4B K
0100 1100 76 4C L
0100 1101 77 4D M
0100 1110 78 4E N
0100 1111 79 4F O
0101 0000 80 50 P
0101 0001 81 51 Q
0101 0010 82 52 R
0101 0011 83 53 S
0101 0100 84 54 T
0101 0101 85 55 U
0101 0110 86 56 V
0101 0111 87 57 W
0101 1000 88 58 X
0101 1001 89 59 Y
0101 1010 90 5A Z
0101 1011 91 5B [
0101 1100 92 5C \
0101 1101 93 5D ]
0101 1110 94 5E ^
0101 1111 95 5F _
0110 0000 96 60 `
0110 0001 97 61 a
0110 0010 98 62 b
0110 0011 99 63 c
0110 0100 100 64 d
0110 0101 101 65 e
0110 0110 102 66 f
0110 0111 103 67 g
0110 1000 104 68 h
0110 1001 105 69 i
0110 1010 106 6A j
0110 1011 107 6B k
0110 1100 108 6C l
0110 1101 109 6D m
0110 1110 110 6E n
0110 1111 111 6F o
0111 0000 112 70 p
0111 0001 113 71 q
0111 0010 114 72 r
0111 0011 115 73 s
0111 0100 116 74 t
0111 0101 117 75 u
0111 0110 118 76 v
0111 0111 119 77 w
0111 1000 120 78 x
0111 1001 121 79 y
0111 1010 122 7A z
0111 1011 123 7B {
0111 1100 124 7C |
0111 1101 125 7D }
0111 1110 126 7E ~

二、乱码

1、文件乱码

当使用编辑器打开文本文件时(如:txt、jsp、HTML、java、js、css……)发生乱码,可能是由于打开时使用了错误的字符集

如下

解决方案

切换正确的字符集即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8yTMZYue-1574241894793)(https://i.loli.net/2019/11/13/EPZtvHOQzVI7Yum.png)]

也存在一种可能,文本写入时即发生乱码写入了错误的字符。此种方式不可逆,基本无法还原。所以,写入文本时一定确保写入的内容编码正确

2、HTML乱码

检查浏览器使用的编码

查看源文件指定的字符集为UTF-8

指定浏览器编码

** 解决方案**

开发时HTML在<meta>中明确指定字符集

3、JSP乱码

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">...</head>...
</html>

JSP在部署后提供给用户使用,会经过三个阶段

  1. JSP生成java文件:这个阶段会使用pageEncoding所定义的编码格式进行转换
  2. java文件生成class文件:这个阶段由服务器tomcat自动使用utf-8编码把java文件转换成字节码class文件
  3. 通过读取class文件展现给用户:这个阶段由tomcat服务器获取字节码内容,通过使用contentType所定义的编码格式展现给用户

解决方案

请在各个环节指定正确的字符集,最好全部指定utf-8

4、GET,POST请求乱码

form表单有两种方法把数据提交给服务器:

1)get提交

get请求时,在前端URIEncode编码两次;

容器接收时,默认ISO-8859-1解码一次;

手动再解码一次。

前端:

url1=encodeURI(url);
url2=encodeURI(url1);

后台:

String name1=request.getParameter("name");
String name2 = java.net.URLDecoder.decode(name1,"UTF-8");

不管容器用的什么编码,都不会有乱码:

url1会把url中的中文编为ASCII码。

url2对url1进行再编码,由于是对ASCII码进行编码,在request.getParameter(“name”)解码的时候,不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确的得到url1。

因为ASCII码用GBK、UTF-8、ISO-8859-1编码的结果是相同的

首先说下客户端(浏览器)的form表单用get方法是如何将数据编码后提交给服务器端的

​ 对于get方法来说,都是把数据串联在请求的url后面作为参数,如:http://localhost:8080/servlet?msg=abc(很常见的一个乱码问题就要出现了,如果url中出现中文或其它特殊字符的话,如:http://localhost:8080/ /servlet?msg=南京,服务器端容易得到乱码),url拼接完成后,浏览器会对url进行URL encode,然后发送给服务器,URL encode的过程就是把部分url做为字符,按照某种编码方式(如:utf-8,gbk等)编码成二进制的字节码,然后每个字节用一个包含3个字符的字符串 “%xy” 表示,其中xy为该字节的两位十六进制表示形式。具体介绍可以看下java.net.URLEncoder类的介绍。

​ 了解了 URL encode的过程,我们能看到2个很重要的问题:

​ 第一:需要URL encode的字符一般都是非ASCII的字符(笼统的讲),再通俗的讲就是除了英文字母以外的文字(如:中文,日文等)都要进行URL encode,所以对于我们来说,都是英文字母的url不会出现服务器得到乱码问题,出现乱码都是url里面带了中文或特殊字符造成的;

​ 第二:URL encode到底按照那种编码方式对字符编码?这里就是浏览器的事情了,而且不同的浏览器有不同的做法,中文版的浏览器一般会默认的使用GBK,通过设置浏览器也可以使用UTF-8,可能不同的用户就有不同的浏览器设置,也就造成不同的编码方式,所以很多网站的做法都是先把url里面的中文或特殊字符用 javascript做URL encode,然后再拼接url提交数据,也就是替浏览器做了URL encode,好处就是网站可以统一get方法提交数据的编码方式。 完成了URL encode,那么现在的url就成了ASCII范围内的字符了,然后以iso-8859-1的编码方式转换成二进制随着请求头一起发送出去。这里想多说几句的是,对于get方法来说,没有请求实体,含有数据的url都在请求头里面,之所以用URL encode,我个人觉的原因是:对于请求头来说最终都是要用iso-8859-1编码方式编码成二进制的101010…的纯数据在互联网上传送,如果直接将含有中文等特殊字符做iso-8859-1编码会丢失信息,所以先做URL encode是有必要的。
服务器端(tomcat)是如何将数据获取到进行解码的。
第一步是先把数据用iso-8859-1进行解码,对于get方法来说,tomcat获取数据的是ASCII范围内的请求头字符,其中的请求url里面带有参数数据,如果参数中有中文等特殊字符,那么目前还是URL encode后的%XY状态,先停下,我们先说下开发人员一般获取数据的过程。通常大家都是request.getParameter(“name”)获取参数数据,我们在request对象或得的数据都是经过解码过的,而解码过程中程序里是无法指定,这里要说下,有很多新手说用 request.setCharacterEncoding(“字符集”)可以指定解码方式,其实是不可以的,看servlet的官方API说明有对此方法的解释:Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().可以看出对于get方法他是无能为力的。那么到底用什么编码方式解码数据的呢,这是tomcat的事情了,默认缺省用的是 iso-8859-1,这样我们就能找到为什么get请求带中文参数为什么在服务器端得到乱码了,原因是在客户端一般都是用UTF-8或GBK对数据 URL encode,这里用iso-8859-1方式URL decoder显然不行,在程序里我们可以直接

Java代码

new String(request.getParameter("name").getBytes("iso-8859-1"),"客户端指定的URL encode编码方式")

还原回字节码,然后用正确的方式解码数据,通常是在tomcat里面做个配置
Xml代码

<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/>

这样是让tomcat在获取数据后用指定的方式URL decoder,URL decoder的介绍在这里

http://blog.csdn.net/vickyway/article/details/46375971

http://www.jb51.net/article/80181.htm

2)post提交

客户端(浏览器)的form表单用post方法是如何将数据编码后提交给服务器端的。
在post方法里所要传送的数据也要URL encode,那么他是用什么编码方式的呢?
在form所在的html文件里如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>,那么post就会用此处指定的编码方式编码。一般大家都认为这段代码是为了让浏览器知道用什么字符集来对网页解释,所以网站都会把它放在html代码的最前端,尽量不出现乱码,其实它还有个作用就是指定form表单的post方法提交数据的 URL encode编码方式。从这里可以看出对于get方法来数,浏览器对数据的URL encode的编码方式是有浏览器设置来决定,(可以用js做统一指定),而post方法,开发人员可以指定。
服务器端(tomcat)是如何将数据获取到进行解码的。
如果用tomcat默认缺省设置,也没做过滤器等编码设置,那么他也是用iso-8859-1解码的,但是request.setCharacterEncoding("字符集")可以派上用场。

我发现上面说的tomcat所做的事情前提都是在请求头里没有指定编码方式,如果请求头里指定了编码方式将按照这种方式编码。
有2篇文章推荐下,地址分别是
深入浅出URL编码:http://www.cnblogs.com/yencain/articles/1321386.html;
表单用post方法提交数据时乱码问题:http://wanghuan8086.javaeye.com/blog/173869

用post很重要的在form所在的html文件里如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>
强烈建议使用post提交

也可以通过base64编码传输,服务端base64解码拿到正确的字符

5、URL包含特殊字符

在HTTP请求时会遇到以下几种情况:

  1. 当字符串数据以url的形式传递给web服务器时,字符串中是不允许出现空格和特殊字符串的
  2. url对字符有限制,比如把一个邮箱放入url,就需要使用urlencode函数。
  3. url转义其实也只是为了符合url的规范而已。因为在标准的url规范中中文和很多的字符是不允许出现在url中的。

解决方案

使用 urlencode (上文已介绍过)

java:

java.net.URLEncoder.encode("要转码的内容","UTF-8"); // 原来单参数方法已经过时。

javaScript:

encodeURI()

6、数据库乱码

1、MySQL环境变量

Session会话变量:
使用show variables like '%char%';可以查看Session会话的字符集变量:

set character_set_server=utf8;
set character_set_database=utf8;
使用SET可以设置不同字符集。但是使用SET设置的字符集都是Session会话级别的,如果新打开一个会话,新会话使用的是默认的字符集。
Global全局变量:
使用show global variables like '%char%';可以查看Global的字符集变量:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZLuomhT7-1574241894801)(https://i.loli.net/2019/11/12/AiQSf3M6umIK82O.png)]

set global character_set_database=utf8;
set global character_set_server=utf8;
使用SET GLOBAL可以设置多个会话的字符集。
使用show charset;查看MySQL支持的字符集和对应字符集的字符序。
MySQL服务重启后,Global的值会被重置为默认值。永久修改Global的值的方法如下:
修改mysql配置文件/etc/my.cnf

[mysqld]
character-set-server=utf8
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

2、MySQL字符集

MySQL服务器可以支持多种字符集,提供了不同级别的设置,包括server级、database级、table级、column级。
MySQL数据库的环境变量查看使用SQL语句show variables like '%char%';
character_set_client:客户端使用的字符集,当客户端向服务器发送请求时,请求以客户端字符集进行编码。
character_set_connection :客户端/数据库建立的通信连接使用的字符集,MySQL服务器接收客户端的查询请求后,将其转换为character_set_connection变量指定的字符集。
character_set_database:数据库服务器中某个数据库的字符集,如果没有默认数据库字符集,使用 character_set_server指定的字符集。
character_set_results:数据库给客户端返回时的字符集,MySQL数据库把结果集和错误信息转换为character_set_results指定的字符集,并发送给客户端。
character_set_server:数据库服务器的字符集,内部操作字符集。
character_set_system:系统元数据(字段名等)使用的字符集
当客户端连接服务器的时候,客户端会将自己想要的字符集名称发给MySQL服务端,然后服务端就会使用字符集去设置character_set_connection、character_set_client、character_set_results。
创建数据库时如果不指定数据库的字符集,默认会使用character_set_server字符集。
创建表时如果不指定表的字符集,默认使用当前数据库字符集。
创建列时如果不指定字符集,默认使用当前表的字符集。

3、MySQL字符集的设置

A、MySQL服务器级字符集
修改MySQL服务器配置文件/etc/my.cnf文件。

[mysqld]
character_set_server=utf8

重启MySQL数据库服务生效。
B、MySQL数据库级字符集:
创建数据库时指定:

CREATE DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]

修改已有的数据库的字符集:

ALTER DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]

ALTER修改只对修改后在数据库上的操作有效。
C、MySQL表级字符集:
创建表时指定:

CREATE TABLE tbl_name (column_list)
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]]

修改表的字符集:

ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]

D、MySQL字段级字符集:
修改已有字段的字符集:

ALTER TABLE table_name MODIFY
column_name {CHAR | VARCHAR | TEXT} (column_length)[CHARACTER SET charset_name][COLLATE collation_name]

MySQL客户端设置:set names utf8;等价于:
set character_set_client=utf8;
set character_set_connection=utf8;
set character_set_results=utf8;
E、客户端字符集
修改MySQL服务器配置文件/etc/my.cnf文件。

[client]
default-character-set=utf8

等价于set names utf8;
会影响会话中的变量character_set_client,character_set_connection 和character_set_results的值。
修改后无需重启MySQL数据库服务即可生效。

4、MySQL字符集的转换过程


A、MySQL服务端收到请求时将请求数据从character_set_client字符集转换为character_set_connection字符集。
B、进行内部操作前将请求数据从character_set_connection字符集转换为内部操作字符集。确定步骤:
–使用每个数据字段的CHARACTER SET设定值;
–若上述值不存在,则使用对应数据表的DEFAULT CHARACTER SET设定值;
–若上述值不存在,则使用对应数据库的DEFAULT CHARACTER SET设定值;
–若上述值不存在,则使用character_set_server字符集设定值;
C、将操作结果从内部操作字符集转换为character_set_results字符集。
D、将character_set_results字符集的执行结果转换为character_set_client字符集,发送到客户端,客户端使用设置的字符集展示结果。

5、MySQL乱码产生的原因

乱码产生的原因如下:
A、存入和取出时对应环节的编码不一致。
B、如果两个字符集之间无法进行无损编码转换,一定会出现乱码。

6、编码无损转换

如果一个使用编码A表示的字符X,转化为编码B的表示形式,而编码B的字符集中并没有X字符,则编码转换是有损的,否则编码转换就是无损的。
由于每个字符集所支持的字符数量是有限的,并且各个字符集涵盖的字符之间存在差异。将UTF-8字符转换为GBK字符时,MySQL内部如果无法在GBK字符集找到一个UTF8字符集中的字符时,就会转换成一个错误标记(0x3F,问号)。
编码无损转换的条件:
A、被转换的字符是否同时在两个字符集中。
B、目标字符集是否能够对不支持字符,保留其原有表达形式。

解决方案

从创建数据库,创建表到连接数据库全部指定统一字符集,并从一而终。


©️ 框架组 以上信息如有不足,请斧正

常见编码及乱码的处理相关推荐

  1. java 问号乱码_Java web中常见编码乱码问题(一)

    最近在看Java web中中文编码问题,特此记录下. 本文将会介绍常见编码方式和Java web中遇到中文乱码问题的常见解决方法: 一.常见编码方式: 1.ASCII 码 众所周知,这是最简单的编码. ...

  2. bug:生产问题,Golang解决csv文件用excel打开中文乱码问题及常见编码和BOM头关系

    bug:Golang解决csv文件用excel打开中文乱码问题 1 场景及分析 场景:今天在生成csv文件之后,测试发现用office和wps打开乱码 分析:经过测试之后发现使用记事本打开不乱码,同时 ...

  3. JSP/ Servlet常见的中文乱码原因

    在开发中,我们经常遇到中文乱码的问题,比方: &浏览器中看到的 Jsp/Servlet 页面中的汉字成了 '?' ?  &浏览器中看到的 Servlet 页面中的汉字都成了乱码  &a ...

  4. 汉字乱码_彻底搞懂这烦人的编码与乱码!

    ❝ 我们平时在处理文本文件或者网络请求时,时不时会遇到乱码的情况,这篇文章就带你彻底搞懂编码和乱码 ❞ 首先,我们要知道,在计算机中,一切都是用0和1来表示的.普通的txt文件.或者客户端发过来的数据 ...

  5. python字符串编码及乱码解决方案

    http://blog.csdn.net/pipisorry/article/details/44136297 字符编码详解 [字符编码ASCII,Unicode和UTF-8] 主要非英文字符集的编码 ...

  6. Computer:字符编码(ASCII编码/GBK编码/BASE64编码/UTF-8编码)的简介、案例应用(python中的编码格式及常见编码问题详解)之详细攻略

    Computer:字符编码(ASCII编码/GBK编码/BASE64编码/UTF-8编码)的简介.案例应用(python中的编码格式及常见编码问题详解)之详细攻略 目录 符串编码(ASCII编码/GB ...

  7. python 乱码 无效_python学习第四天:python基础(字符编码和乱码到底咋回事儿)...

    字符编码 这得从字符编码开始说起: 字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题.因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理. 最早的计算机在设计时采 ...

  8. Java 字符的 编码 与 乱码 和恢复

    这里写目录标题 常见非Unicode编码 1.ASCII 2.ISO 8859-1 3.Windows-1252 4.GB2312 5.GBK 6.GB18030 7.Big5 8.编码汇总 2.3. ...

  9. java printwriter乱码_Java servlet 使用 PrintWriter 时的编码与乱码的示例代码

    在前面的网页中的编码与乱码系列中,曾多次提到使用 servlet 方式构建的动态响应流,不过在那里都是直接使用字节流的方式,不过,更为常见的方式是使用字符流.而在前面,又谈到了 Java 字节流与字符 ...

最新文章

  1. OSSIM系统——mysql的使用
  2. mybatis 分页需要的jar包下载_064、MyBatis
  3. 在ASP.NET MVC5中使用特性路由
  4. Replica Sets+Sharding方案之真枪实弹篇
  5. R学习笔记:文档间函数调用
  6. android -自定义view
  7. 一文彻底搞懂字符串、字符串常量池原理
  8. verilog中~在判断中的作用
  9. 使用 cajViewer 将 caj文件 转换 pdf文件
  10. 交换机、路由器、服务器组网
  11. Windows8 最新泄漏版试用体验与下载
  12. 人均 3.6万行代码, C++ 成最烫手山药:腾讯首度披露技术研发数据!
  13. cad标注样式快捷键_制图大神最常用的六大类CAD快捷命令,学会CAD就是这么简单...
  14. 基于JAVA的停车场管理系统
  15. 有点厉害!用12万行代码堆出来个蔡徐坤,关键是能跑能跳!
  16. 遗传算法matlab_史上最强的MATLAB自学网站,你收藏了吗???
  17. 带你去看不一样的《西游记》
  18. 精选国外知名网站手机版网页设计欣赏
  19. 清除远程桌面登录记录
  20. 七天入门统计力学-第1天 基础知识及基本概念

热门文章

  1. “想去夏威夷?公司请你去!” 在硅谷工作也太太太太爽爽爽了吧!​
  2. WARNING: NMS time limit 1.060s exceeded
  3. ffmpeg使用参数介绍
  4. CSS制作的导航菜单向上箭头
  5. 从双非文科生到年薪50万大厂女码农,我用了3年
  6. 本地计算机添加网络打印机共享,手把手教你win7如何设置局域网共享打印机
  7. STL——set用法
  8. AirPower的无线充电板
  9. ifstream seekg 问题
  10. 电玩设计无孔不入:摇杆造型、可发声的电灯开关