发布时间:2023-08-31 10:00
写这个的目的就是平时经常遇见一串字符串,看起来像是被加密或者是编码过,但是无从下手,发到群里问大佬,大佬一眼就能看出来是什么编码,比如经过base64加密过、经过md5加密过、被转换成了16进制。所以写这篇文章就是想整理一下常见的编码的特点。我目前比较经常见到的:Ascii、unicode、HEX、URL、base64、MD5
1.Ascii编码
Ascii编码就是我们在电脑上看到的字符(输入法切换到半角后输出的字符),比如:
英文字符:English is very important.
标点符号:./?!@#$%^&*()_+
开始有127个,叫标准Ascii码,符合国际标准:
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。
65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
后来又新加了128个(从128-255),叫扩展Assci码。扩展ascii码不再是国际标准。
我们使用的汉字编码一般是GBK编码或者UTF-8编码。
2.Unicode
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。
Unicode仅仅只是一个字符集,规定了符合对应的二进制代码,至于这个二进制代码如何存储则没有任何规定。它的想法很简单,就是为每个字符规定一个用来表示该字符的数字,仅此而已。以汉字“汉”为例,它的 Unicode 码点是 0x6c49,对应的二进制数是 110110001001001,二进制数有 15 位,这也就说明了它至少需要 2 个字节来表示。可以想象,在 Unicode 字典中往后的字符可能就需要 3 个字节或者 4 个字节,甚至更多字节来表示了。
这就导致了一些问题,计算机怎么知道你这个 2 个字节表示的是一个字符,而不是分别表示两个字符呢?这里我们可能会想到,那就取个最大的,假如 Unicode 中最大的字符用 4 字节就可以表示了,那么我们就将所有的字符都用 4 个字节来表示,不够的就往前面补 0。这样确实可以解决编码问题,但是却造成了空间的极大浪费,如果是一个英文文档,那文件大小就大出了 3 倍,这显然是无法接受的。
互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。
UTF-8 是 Unicode 的实现方式之一。它最大的一个特点就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。举个例子:严的 Unicode码 是4E25,UTF-8 编码是E4B8A5,两者是不一样的。它们之间的转换可以通过程序实现。
3.Hex
十六进制编码,Hex编码就是把一个8位的字节数据用两个十六进制数展示出来,编码时,将8位二进制码重新分组成两个4位的字节,其中一个字节的低4位是原字节的高四位,另一个字节的低4位是原数据的低4位,高4位都补0,然后输出这两个字节对应十六进制数字作为编码,Hex编码后的长度是源数据的2倍。
ASCII码G的Hex编码过程:
Ascii码:G(71)
二进制码:0100-0111
重新分组:0000-0100 0000-0111
十六进制: 4 7
Hex编码:47
4.URL
说到URL编码,我们先要说一下URL。URL(Uniform Resource Locator,统一资源定位符)是标识Web资源的唯一标识符,通过它可获取其标识的资源。通俗的讲URL就是网址,通过网址我们可以访问到与网址对应的资源,比如通过小明家的地址可以找到小明。
URL编码并不会对所有的字符都进行编码,而是只会对特殊字符进行编码。举个例子:
url:
www.jianshu.com/index.php
www.jianshu.com/index.php?name1=value&name2=value
www.jianshu.com/index.php?name1=简书&name2=¥
编码结果:
www.jianshu.com/index.php
www.jianshu.com/index.php?name1=value&name2=value
www.jianshu.com/index.php?name1=%E7%AE%80%E4%B9%A6&name2=%EF%BF%A5
从上面的例子可以看到,第一句和第二句进行编码前后没有任何变化,而第三句中的中文和中文符号都被进行url编码了,那么什么样的字符会被url编码呢?在ASCII编码0x20 ~ 0x7e范围内的一部分字符和范围外的所有字符都会被url编码,同时也包括汉字等其他文字。
值得注意的是,在浏览器的地址栏输入数据或者使用表单提交数据的时候都会默认进行一次url编码,这是为了防止提交的数据中出现特殊字符,所以在接收到数据后都会先进行一次url解码,然后再对数据进行处理。
5.Base64
Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方=64,所以每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。它可用来作为电子邮件的传输编码。虽然这样的初衷,是为了满足电子邮件中不能直接使用非ASCII码字符的规定,但是也有其他重要的意义:a)所有的二进制文件,都可以因此转化为可打印的文本编码,使用文本软件进行编辑;b)能够对文本进行简单的加密。
Base64的编码转换方式:所谓Base64,就是说选出64个字符----小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符)----作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。具体来说,转换方式可以分为四步:
第一步,将每三个字节作为一组,一共是24个二进制位。
第二步,将这24个二进制位分为四组,每个组有6个二进制位。
第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。
第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y
因为Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。
Base64除了可以转换字符外,还可以转换图片,jpg、png等格式均可以转换为Base64编码。
除了Base64编码,相似的还有Base32、Base16编码等。
6.MD5
MD5并不是实际意义上的编码,它是一种加密算法,之所以要进行编码是为了加密。维基百科:
MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。
MD5 用的是哈希函数,它的典型应用是对一段信息产生信息摘要,以防止被篡改。严格来说,MD5 不是一种加密算法而是摘要算法。无论是多长的输入,MD5都会输出长度为128bits的一个串 (通常用16 进制表示为32个字符)。
每一段信息的MD5值都是唯一的,但是它有可能通过撞库被“解密”出来,所以它的安全性并不是非常高。
7.各个编码的特点
测试字符串:这是一条用于测试的字符串[\-+*,.?;':@#$%^&"(*)]/This is a string for testing
ASCII码:\u8fd9\u662f\u4e00\u6761\u7528\u4e8e\u6d4b\u8bd5\u7684\u5b57\u7b26\u4e32\u005b\u005c\u002d\u002b
\u002a\u002c\u002e\u003f\u003b\u0027\u003a\u0040\u0023\u0024\u0025\u005e\u0026\u0022\u0028\u002a\u0029
\u005d\u002f\u0054\u0068\u0069\u0073\u0020\u0069\u0073\u0020\u0061\u0020\u0073\u0074\u0072\u0069\u006e
\u0067\u0020\u0066\u006f\u0072\u0020\u0074\u0065\u0073\u0074\u0069\u006e\u0067
Unicode编码:这是一条用于测试的字符
串[\-+*,.?;':@#$%^&"(
*)]/This is a strin
g for testing
UTF-8编码:这是一条用于测试的字符
串[\-+*,.?;':@#$%^&"(*)]/This is a string for testing
Hex编码:E8BF99E698AFE4B880E69DA1E794A8E4BA8EE6B58BE8AF95E79A84E5AD97E7ACA6E4B8B25B5C2D2B2A2C2E3F3B273
A402324255E2622282A295D2F54686973206973206120737472696E6720666F722074657374696E67
URL编码:%e8%bf%99%e6%98%af%e4%b8%80%e6%9d%a1%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84%e5%ad%97%e7
%ac%a6%e4%b8%b2%5b%5c-%2b*%2c.%3f%3b%27%3a%40%23%24%25%5e%26%22(*)%5d%2fThis+is+a+string+for+testing
Base64编码:(Base64加密算法不唯一,所以加密结果也不唯一,当然不同的加密结果要用相应的方法解密)
6L+Z5piv5LiA5p2h55So5LqO5rWL6K+V55qE5a2X56ym5LiyW1wtKyosLj87JiMzOTs6QCMkJV4mIigqKV0vVGhpcy
BpcyBhIHN0cmluZyBmb3IgdGVzdGluZw==
6L+Z5piv5LiA5p2h55So5LqO5rWL6K+V55qE5a2X56ym5LiyW1wtKyosLj87JzpAIyQlXiYiKCopXS9UaGlzIGlzIGEgc3RyaW5nI
GZvciB0ZXN0aW5n
MD5编码:A8D7CBA2A0F9CD9859EBB9E5C7A11F96
/*注:以上颜色没有特殊含义,我也不知道为什么会变色。。。*/
下面是我整理的一些在线工具: