再也没有看不懂的编码!

2019-02-17

文章共计 - 3.5k 字 阅读需要 - 13 分钟


再也没有看不懂的编码!

2018-12-22

这一阵子做的比赛突然感觉,自己基础真的是太差了。月赛的base32码硬生生以为是base64,这才反应过来看到编码就直接扔一波工具解码碰大运,错了乱码就解不开了。其实对于编码的内容和性质、一般的形式等等跟不讲不出什么所以然来。吃了这次的亏以后,决定重新一点一点一步一步的从最基本的东西开始积累,不要在急着做一些表面的东西。

2019/2/17

终于把这篇文章算是更新完结了。
揣摩了大佬的编码讲解文章,修改和增添了一些内容。
在未来遇到更多的编码时会不断的向这其中添加。


0x00- - 简介

什么是编码?区分编码和加密以及hash在于,编码只是信息的转换,其目的不在于隐蔽消息的内容,而在于方便传输以及保证传输数据内容不失真等。重点在转换为方便计算机传输的二进制数据。
所以个人认为,编码处理后的信息,仍可以视为是明文传输。

列一下目录:

  • normal decode
    • ASCII
    • Unicode
    • UTF-8
    • url
    • html编码
  • base
    • base64
    • base32
    • base16
    • (extends)UTF-7
    • Quoted-printable
    • uuencode/uudecode
    • XXencoding
  • js decode
    • aaencode
    • jjencode
    • jsfuck
    • 社会主义核心价值观编码
  • others
    • 正则表达式
    • Morse code
    • 盲文编码
    • 垃圾邮件兰格密码

0x01- - normal decode

这一部分写一些最最最耳熟能详的编码格式。

ascii码

定义
不知道 ASCII 码是不是最早意义上的编码,这种编码的出现是为了解决计算机使用二进制来进行运算和存储所有的数据。为了使用二进制来表示我们生活中所使用的字符(abcd)或是罗马数字,美国有关的标准化组织就出台了 ASCII 编码,统一规定了上述常用符号用哪些二进制数来表示。

编码方式
ASCII 码通常使用 7bit / 8bit 来表示一个字符。二进制所表示的十进制在这个表中一一对应即可...

kyH7t0.md.jpg

小结

  • 1.标准ascii码是7bit+1bit补零。所以在标准的ascii码中只有127个字符
  • 2.数字部分48-57,大写字母65-90,小写字母96到122

Unicode

定义
在ascii码出现之后,各个国家为了适应自己国家语言分分独立研发的编码体制。如GB2312,来弥(mi)补ascii码的不足。出现了非常混乱的编码现象。因此Unicode应情而生。
Unicode也叫统一码,万国码。满足了跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

编码方式
Unicode统一使用两个字节表示一个字符,对于英文只需要把高字节填零即可。这样既能表示了英文也可以表示中文。因此对于英文的Unicode编码就是明文本身(大写会变为小写)。

Unicode在线转换工具

UTF-8

定义
看了Unicode编码后,很容易发现这样的编码一下子就把存储量翻了一个倍。对于英文来说,浪费了大量的存储空间。于是又产生了UTF-8编码。
UTF-8就是在Unicode的编码上,对Unicode进行分组处理。

编码方式

处理方式如下表:

Unicode编码(十六进制) UTF-8 字节流(二进制)
000000-00007F 0xxxxxxx
000080-0007FF 110xxxxx 10xxxxxx
000800-00FFFF 1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

对不同Unicode编码段进行不同字节的编码处理。节省了大量的空间。

例:Unicode编码0x20C30在0x010000-0x10FFFF之间,使用4字节模板:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。将0x20C30写成21位二进制数字(不足21位就在前面补0):0 0010 0000 1100 0011 0000,用这个比特流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即F0 A0 B0 B0。
同样的还存在UTF-16、UTF-32,但是只有UTF-8才兼容ASCII码

Url编码

对于url编码,是因为对于url有许多歧义的符号。如:'&'、'=' 等。
我们依旧从定义开始了解。

定义

讲到底,到底什么是url。不知道,继续找度娘:
url(Uniform/Universal Resource Locator)是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
它最初是由蒂姆·伯纳斯·李发明用来作为万维网的地址。现在它已经被万维网联盟编制为互联网标准RFC1738了。(来源百度百科)

P.S.又发现了一个和这个东西很像的一个玩意,叫做URI,那么在简单地写一下什么是URI吧。

URI:(Uniform Resource Identifier)统一资源标识符,URI 属于 URL 更低层次的抽象,一种字符串文本标准。就是说,URI 属于父类,而 URL 属于 URI 的子类。URL 是 URI 的一个子集。

URL的格式如下:协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志。
(标准化一下):scheme://host[:port#]/path/.../[;url-params][?query-string][#anchor]

依旧举个例子比较好理解:例如我的一篇博客的地址:
https://blog.dvkunion.cn/2018/10/17/python3-learning①/

它的第一部分--scheme:协议/模式,在上例中就是指 'https://' 部分
第二部分--authority:IP/域名+端口号,在上例中就是指 'dvkunion.github.io' 部分,端口号被省略,默认为80端口。
第三部分--path:路径,在上例中就是指 '/2018/10/17/....' 部分,指访问的主机目录。
可能后面还会带有?(query)和一些参数(fragment),基本结构就是这样。

根据文档规定,URL中只允许出现 大小写字母(a-z)&(A-Z)、数字(0-9)、'-'、'_'、'~'、'·' 这些符号。
保留字符有:! * ' ( ) ; : @ & = + $ , / ? # [ ]
不安全字符:空格、引号、尖括号、#、%、{}|^[]`~之类。

编码方式

URL也称为 %编码,其编码方式非常简单,只需要使用US-ASCII将字符转化为十六进制字符并加一个%即可。
要注意URL编码采用的是ASCII而不是Unicode,所以url内不能存在中文。
如下是js三个函数的url编码规则:即不对一下字符进行编码。

escape(69个):/@+-._0-9a-zA-Z
encodeURI(82个):!#$&'()
+,/:;=?@-.~0-9a-zA-Z
encodeURIComponent(71个):!'()*-.
~0-9a-zA-Z

Html编码

定义
同url一样,html编码也是为了防止歧义。

编码方式
其实常用的只是过滤了几个关键的字符,其他的依旧是十六进制的表示ASCII码的方法。

字符 十进制 十六进制数字 转义字符
" " " "
& & & &
< &#60; &#x3C; &lt;
> &#62; &#x3E; &gt;
不断开空格 &#160; &#xA0; &nbsp;

注意不能丢掉分号!

0x02- - base

吃过最多次亏的一个编码,最早认为后面有两个==的就是base64...而且只知道一个base64...
base全家福

base64

定义

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。

Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。(来源于百度百科)

由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法。

base64特别适合在http,mime协议下快速传输数据。

编码方式

如图可见,base64用64个可以打印的ASCII字符来转换任意的二进制,2^6=64,所以base64以6位一分割,且分割的之前的二进制应该为24的倍数(6、8的最小公倍数),不足的位数用base通用补码'='补齐。

举个例子会更好理解:

当位数不足时候,先用0把前面的凑出一个6位,再用'='可以补出24的倍数即可。所以,可以总结出:

在Base64中4个字符为一个块,对应铭文中的三个字符。因此Base64编码后会比原文本多出1/3左右

因此我们可以轻松的依此计算:DVKD---->RFZLRA==;DVKDV---->RFZLRFY=;DVKDVK---->RFZLRFZL

base32

定义

Base32看名字就知道和64不会相差很多,只是用32个字符来进行编码。2^5=32,所以5位一分割,公倍数40(5,8)。所以必须是40倍数。

编码方式

明文五个字符--->转码八个字符。

base16

定义

Base家族也就这样了,大同小异。16个字符,2^4=16,4位一分割,公倍数8(4,8)。8的倍数即可。

编码方式

总结

  • 1.base64中包含大写字母、小写字母、数字1~9以及特殊字符'+'和'/'
  • 2.base64为6bit一转换,所以编码后通常比明文多1/3
  • 3.base64常用于传输,注意是传输,如UTF-8编码的中文,可以通过Base64进行良好的传输。
  • 4.base32中只包含大写字母、数字2~7
  • 5.base32为5bit一转换,由于其编码不包含'',其结果可以用作文件名。
  • 6.base32比base64多出 20% 左右的大小,通常比明文多3/5
  • 7.base16中只包含数字0~9以及大写字母'A'~'F'
  • 8.base16为4bit一转换,所以编码结果准确的为明文的一倍,且不存在填充用的'='

UTF-7

定义
UTF-7 是base64的修改版,主要目的是为了将UTF-16的数据用Base64的方法进行编码传输。

编码方式
UTF-7编码的规则为:

1> UTF16小于等于 0x7F 的字符,采用ASCII编码;
2> UTF16大于0x7F的字符,采用Base64编码,然后在首尾分别加上+-;
3> UTF-7编码后,所有字符均小于等于 0x7F。

UTF-7在线工具

Quoted-printable

定义
同base64一样,Quoted-printable也是用于满足将非ASCII码转化为ASCII码。可译为“可打印字符引用编码”、“使用可打印字符的编码”。当非ASCII字符较少时,Quoted-printable有着较好的可读性。

编码方式

Quoted-printable编码规则为:将任意一个8 bit 表示为:一个'='和两个十六进制字符。

Quoted-printable在线工具

uuencode/uudecode

定义

uuencode这个名字是衍生自"Unix-to-Unix encoding",原先是Unix系统下将二进制的资料借由uucp邮件系统传输的一个编码程式,是一种二进制到文字的编码。

加密方式
uuencode编码序列:从ascii码的32位算为uudecode的0位。
uuencode只是格式复杂。其编码同base64一样,只是每一组都要加32。

例如:cat 加密后-> #8V%T
begin 644 为uudecode标识。

begin 644 cat.txt
#8V%T
`
end

XXencode

定义

Xxencode是一种类似于uuencode的一种二进制到文字的编码,它只使用字母数字字符,以及加号和减号。也是一种用于传输文件的编码格式。

编码方式
xxencode编码序列: '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
uuencode不去减32直接转化为xxencode码就是xxencode

uuencode && xxencode 工具

0x03- - JS

在url中提到,js对url有三种编码函数,其不编码的字符分别如下:
escape(69个):/@+-._0-9a-zA-Z
encodeURI(82个):!#$&'()
+,/:;=?@-.~0-9a-zA-Z
encodeURIComponent(71个):!'()*-.
~0-9a-zA-Z

同时js还有着几种特殊的编码

Aencode

一种将js编码转化为颜文字的编码格式
AAencode在线工具-1
AAdecode在线工具-2

JJencode

一种将js编码转化为非正常编码的格式
JJencode在线工具

JSfuck

一种将js编码转化为![]等符号的编码格式。
jsfuck在线工具

基本js的加密都是不可逆的,所以只能在控制台观察一下运行结果。

社会主义核心价值观编码

...这个第一次见到时候也是挺无语的...
js源码开放
在线工具-1
在线工具-2 (这个很强大)

0x04- - Others

Morse code

这个就已经很古老了.....直接对应表查表就好了。
有些地方把这个算作密码......我觉得还是莫尔斯还是一种编码的性质,作为信息的传输作用,并没有隐藏信息的功能。

莫尔斯电码表:
k69H4e.md.jpg

在线文字转莫尔斯电码工具

参考链接

0.![kyH7t0.md.jpg : https://blog.dvkunion.cn/img/kyH7t0.md.jpg]
1.Unicode在线转换工具 : http://www.bejson.com/convert/unicode_chinese/
2.base全家福 : https://www.qqxiuzi.cn/bianma/base.php?type=16
9.UTF-7在线工具 : http://toolswebtop.com/text/process/decode/UTF-7
10.Quoted-printable在线工具 : https://www.w3cschool.cn/tools/index?name=decode_encode_tool
11.uuencode && xxencode 工具 : http://web.chacuo.net/charsetxxencode
12.AAencode在线工具-1 : https://www.sojson.com/aaencode.html
13.AAdecode在线工具-2 : https://tool.zcmzcm.org/aadecode
14.JJencode在线工具 : https://www.sojson.com/jjencode.html
15.jsfuck在线工具 : http://utf-8.jp/public/jsfuck.html
16.js源码开放 : https://github.com/sym233/core-values-encoder
17.在线工具-1 : https://sym233.github.io/core-values-encoder/
18.在线工具-2 : https://atool.vip/morse
19.![k69H4e.md.jpg : https://blog.dvkunion.cn/img/k69H4e.md.jpg]
20.在线文字转莫尔斯电码工具 : http://www.atool.org/morse.php

☡ 留言板 ☡