加密、Hash、序列化和字符集
古典密码学
-
起源 :古代战争
-
移位式加密 :密码帮
- 加密算法 :缠绕木棒后书写
- 密钥 :木棒的尺寸规格
-
替换式加密
按规则使⽤不同的⽂字来替换掉原先的⽂字来进⾏加密。- 加密算法 :替换文字
- 密钥 :替换的码表
1 | 码表: |
现在密码学
- 不⽌可以⽤于⽂字内容,还可以⽤于各种⼆进制数据
- ⾮对称加密的出现使得密码学有了更⼴泛的⽤途:数字签名
对称加密
-
原理: 通信双⽅使⽤同⼀个密钥,使⽤加密算法配合上密钥来加密,解密时使⽤加密过程的完全逆过程配合密钥来进⾏解密。
-
经典算法 :DES(56 位密钥,密钥太短⽽逐渐被弃⽤)、AES(128 位、192 位、256 位密钥,现在最流⾏)
-
缺点 :密钥泄露:不能在不安全⽹络上传输密钥,⼀旦密钥泄露则加密通信失败。
非对称加密
- 原理:使⽤公钥对数据进⾏加密得到密⽂;使⽤私钥对数据进⾏解密得到原数据。
- 延伸⽤途:数字签名。
- 经典算法:RSA(可⽤于加密和签名)、DSA(仅⽤于签名,但速度更快)
- 优缺点
- 优点:可以在不安全⽹络上传输密钥
- 缺点:计算复杂,因此性能相⽐对称加密差很多
数字签名
密码学密钥和登录密码
- 密钥(key)
- 场景:⽤于加密和解密
- ⽬的:保证数据被盗时不会被⼈读懂内容
- 焦点:数据
- 登录密码(password)
- 场景:⽤户进⼊⽹站或游戏前的身份验证
- ⽬的:数据提供⽅或应⽤服务⽅对账户拥有者数据的保护,保证「你是你」的时候才提供权限
- 焦点:身份
Base64
将⼆进制数据转换成由 64 个字符组成的字符串的编码算法
-
什么是⼆进制数据?
- ⼴义:所有计算机数据都是⼆进制数据
- 狭义:⾮⽂本数据即⼆进制数据
-
算法
将原数据每 6 位对应成 Base 64 索引表中的⼀个字符编排成⼀个字符串(每个字符 8 位)。
- Base64 索引表
-
编码示例
- 把「Man」进⾏ Base64 编码
- Base64 的末尾补⾜
- 把「Man」进⾏ Base64 编码
-
⽤途
- 将⼆进制数据扩充了储存和传输途径(例如可以把数据保存到⽂本⽂件、可以通过聊天对话框或短信形式发送⼆进制数据、可以在 URL 中加⼊简单的⼆进制数据)
- 普通的字符串在经过 Base64 编码后的结果会变得⾁眼不可读,因此可以适⽤于⼀定条件下的防偷窥(较少⽤)
-
缺点
因为⾃身的原理(6 位变 8 位),因此每次 Base64 编码之后,数据都会增⼤约 1/3,所以会影响存储和传输性能。
「Base64 加密图⽚传输更安全和⾼效」???
不。⾸先,Base64 并不是加密;另外,Base64 会导致数据增⼤ 1/3,降低⽹络性能,增⼤⽤户流量开销,是画蛇添⾜的⼿段。(最好不要拿来diss 你们公司的后端哟,友善)
Base64 对图⽚进⾏编码的⽤于在于,有时需要使⽤⽂本形式来传输图⽚。除此之外,完全没必要使⽤ Base64 对图⽚进⾏额外处理。
变种:Base58 (存储比特币地址)
⽐特币使⽤的编码⽅式,去掉了 Base64 中的数字 “0”,字⺟⼤写 “O”,字⺟⼤写 “I”,和字⺟⼩写"l",以及 “+” 和 “/” 符号,⽤于⽐特币地址的表示。
Base58 对于 Base64 的改动,主要⽬的在于⽤户的便捷性。由于去掉了难以区分的字符,使得Base58 对于「⼈⼯抄写」更加⽅便。另外,去掉了 “+” “/” 号后也让⼤多数的软件可以⽅便双击选取。
URL 使⽤的百分号编码
在 URL 的字符串中,对⼀些不⽤于特殊⽤途的保留字符,使⽤百分号 “%” 为前缀进⾏单独编码,以避免出现解析错误。
⽬的:消除歧义,避免解析错误
例如,要在 http://hencoder.com/users 后⾯添加查询字符串,查询 name 为「隐匿&伟⼤」的⽤户,如果直接写成 http://hencoder.com/user/?name=隐匿&伟⼤ ,"&" 符号就会被解析为分隔符号,因此需要对它进⾏转码,转码后的 URL 为 http://hencoder.com/user/?name=隐匿&伟⼤ 。
这种编码仅⽤于 URL,⽬的是避免解析错误的出现。
压缩与解压缩
含义
- 压缩:将数据使⽤更具有存储优势的编码算法进⾏编码。(把数据换⼀种⽅式来存储,以减⼩存储空间)
- 解压缩:将压缩数据解码还原成原来的形式,以⽅便使⽤。(把压缩后的数据还原成原先的形式,以便使⽤)
⽬的
减⼩数据占⽤的存储空间。
粗暴算法举例
将下⾯⽂本内容压缩:
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
使⽤某种算法压缩后的数据为:
1 | compress:a:1062;b:105 |
- 注:具体的压缩场景有很多,因此压缩算法也会复杂得多,上⾯只是⼀个原型算法。
压缩是编码吗?
是。所谓编码,即把数据从⼀种形式转换为另⼀种形式。压缩过程属于编码过程,
解压缩过程属于解码过程。
常⻅压缩算法
DEFLATE、JPEG、MP3 等
图⽚与⾳频、视频编解码
含义
将图像、⾳频、视频数据通过编码来转换成存档形式(编码),以及从存档形式转换回来(解码)。
图⽚的编码:把图像数据写成 JPG、PNG 等⽂件的编码格式。
图⽚的解码:把 JPG、PNG 等⽂件中的数据解析成标准的图像数据。
⾳频与视频的编码与上⾯的图⽚编码同理。
⽬的
存储和压缩媒体数据(⼤多数媒体编码算法会压缩数据,但不是全部)。
图⽚压缩粗暴算法举例
⼀张纯⽩(⽩⾊的 16 进制数值为 0xffffff)的 64x64 不透明像素图⽚,原数据格式⼤致为:
1 | width:64;height:64;ffffffffffffffffffffffffffffffffffffffffffffffffffffffff |
使⽤某种算法压缩后的数据为:
1 | width:64;height:64;ffffff:[0,0]-[63,63] |
- 具体的压缩场景有很多,因此压缩算法也会复杂得多,上⾯只是⼀个原型算法。
序列化
把数据对象(⼀般是内存中的,例如 JVM 中的对象)转换成字节序列的过程。对象在程序内存⾥的存放形式是散乱的(存放在不同的内存区域、并且由引⽤进⾏连接),通过序列化可以把内存中的对象转换成⼀个字节序列,从⽽使⽤ byte[] 等形式进⾏本地存储或⽹络传输,在需要的时候重新组装(反序列化)来使⽤。
⽬的
让内存中的对象可以被储存和传输。
序列化是编码吗?和编码的区别 ?
不是 ,编码是把数据由⼀种数据格式转换成另⼀种数据格式;⽽序列化是把数据由内存中的对象(⽽不是某种具体的格式)转换成字节序列。
Hash
定义
把任意数据转换成指定⼤⼩范围(通常很⼩,例如 256 字节以内)的数据。
经典算法
MD5、SHA1、SHA256 等
作⽤
相当于从数据中提出摘要信息,因此最主要⽤途是数字指纹。
Hash 的实际⽤途:唯⼀性验证
例如 Java 中的 hashCode() ⽅法。
-
怎么重写 hashCode ⽅法?
把 equals() ⽅法中的每个⽤于判断相等的变量都放进 hashCode() 中,⼀起⽣成⼀个尽量不会碰撞的整数即可 -
为什么每次重写 equals() ⽅法都需要?因为你要把新的判断条件放进 hashCode() 啊
Hash 的实际⽤途:数据完整性验证
从⽹络上下载⽂件后,通过⽐对⽂件的 Hash 值(例如 MD5、SHA1),可以确认下载的⽂件是否有损坏。如果下载的⽂件 Hash 值和⽂件提供⽅给出的 Hash 值⼀致,则证明下载的⽂件是完好⽆损的。
Hash 的实际⽤途:快速查找
HashMap
Hash 的实际⽤途:隐私保护
当重要数据必须暴露的时候,有事可以选择暴露它的 Hash 值(例如 MD5),以保障原数据的安全。
例如 ⽹站登录时,可以只保存⽤户密码的 Hash 值,在每次登录验证时只需要将输⼊的密码的 Hash值和数据库中保存的 Hash 值作⽐对就好,⽹站⽆需知道⽤户的密码。这样,当⽹站数据失窃时,⽤户不会因为⾃⼰的密码被盗导致其他⽹站的安全也受到威胁。
- 注意:这不属于加密。
Hash 是编码吗?
不是。 Hash 是单向过程,往往是不可逆的,⽆法进⾏逆向恢复操作,因此 Hash 不属于编码。
Hash 是加密吗?
不是。Hash 是单向过程,⽆法进⾏逆向回复操作,因此 Hash 不属于加密。(记住,MD5 不是加密!)
字符集
- 含义 :⼀个由整数向现实世界中的⽂字符号的 Map
- 分⽀:
- ASCII:128 个字符,1 字节
- ISO-8859-1:对 ASCII 进⾏扩充,1 字节
- Unicode:13 万个字符,多字节
- UTF-8:Unicode 的编码分⽀
- UTF-16 :Unicode 的编码分⽀
- GBK / GB2312 / GB18030:中国⾃研标准,多字节,字符集 + 编码