编码、加密、Hash、序列化和字符集

1,301 阅读7分钟

这些东西经常会被用到,但需要真正理解才能正确使用
相关词:MD5、SHA1、 RSA、DSA、AES、BASE64、encoded URL、Unicode、UTF一8、GBK、IS0一8859一1.....

密码学

  • 起源:古代战争--古典密码学
  • 移位式加密--密码棒
    • 长这样 1
    • 密码棒包含了两个核心元素
      • 加密算法:缠绕木棒后书写
      • 密钥:木棒的尺寸规格
  • 替换式加密
    • 加密算法:替换文字
    • 秘钥:码表

现代密码学

不止可以用于文字内容,还可以用于各种二进制数据。

对称加密

  • 原理:使用秘钥和加密算法对数据进行转换,得到的无意义数据即为密文;使用密钥和解密算法对密文进行逆向转换,得到原数据
  • 工作模型
    • 2
  • 经典算法:DES(56位,因为秘钥太短已被弃用),AES(128,192,256位)

非对称加密

原理:

使用公钥对数据进行加密得到密文;使用私钥对数据进行解密得到原数据。

工作模型

对称加密缺点:中间人攻击

非对称加密,即便中间节点截获了加密秘钥,也无法破解密文

  • 加密密文对应的就是公钥↓↓↓,解密秘文对应着私钥↓↓↓

延伸用途: 数字签名

  • 公钥和私钥可以互相解密

签名与验证

签名过程
加密+签名

经典算法:RSA,DSA

  • RSA 可以用来加密也可以用来签名
  • DSA 只能用来签名,签名验证的时候速度更快,如比特币椭圆曲线算法采用的就是DSA

优缺点

  • 优点:在不安全的网络上传输秘钥
  • 缺点:计算复杂,性能比对称加密差很多

密码学秘钥和登录密码

秘钥(key):

  • 场景:用于加密和解密
  • 目的:保证数据被盗时不会被人读懂内容
  • 焦点:数据

登录密码(password):

  • 场景:用户进入网站或游戏前的身份验证
  • 目的:数据提供方或应用服务方对账户拥有者数据的保护,保证【你是你】的时候才提供权限
  • 焦点:身份/通行码

Base64

将==二进制数据==转换成==由64个字符组成的字符串的编码算法==
(64个字符串 A-Za-z0-9+/)

二进制数据

  • 实质上:任何的计算机数据
  • 狭义上:非文本数据

用途

  • 让元数据具有字符串所具有的特性,可以放在URL中传输、可以保存到文本文件、可以通过普通的聊天软件进行文本传输
  • 把原本人眼可以读懂的字符串变成读不懂的字符串,降低偷窥风险

Base64加密传输图片,可以更安全更高效,真的么

不会

  • 加密算法是公开的,所以不会更安全
  • 每次加密体积增大三分之一,所以也不会更高效

变种

Base58

  • 在Base64基础上去掉了大写的O和0(因为它们长得很像),大写的I和小写的l,+和/
  • 用于比特币存储地址
    • O和0,大写的I和小写的l防止手抄地址看错写错

    • +和/,为了计算机打字方便,复制等

URL encoding

如下,在浏览器地址栏中输入地址,然后粘贴到其他文本编辑器中,会被转义

压缩和解压缩

压缩

把数据换一种方式来存储,以减小存储空间

解压缩

把压缩后的数据还原成原先的形式,以便使用

常见压缩算法

  • DEFLATE(zip的压缩算法)
  • JPEG
  • MP3

如:文本压缩

//原文
aaaaaaaaaaaaaaabbbbbb

//算法压缩
//使用dsh算法压缩,压缩之后变小
dsh:a:15;b:6

//原文
ababababababababab
//使用压缩算反,压缩之后变大了
a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1

图片压缩:

//原图
width=100;height=100;ff0000ff0000ff0000...(10000个红色像素点)

//算法压缩
dshImg:type=jpeg;width=100;height=100;data=[0,0-99,99]:ff0000

压缩属于编码么?

属于,符合能够编过去编回来的特点

  • ==编码==这个词并没有官方的定义或者标准;
  • 通常我们所说的编码指的是 使用固定的规则或算法把数据从A格式转换成B格式并且能转换回来而且还不会丢失信息,如Base64

媒体数据的编码

什么是图片、音频、视频的编解码?

  • 图片的编码:把图像数据写成JPG、PNG等文件的编码格式。
  • 图片的解码:把JPG、PNG等文件中的数据解析成标准的图像数据。
  • 音频、视频的编解码

有损压缩/无损压缩

  • 感官相关的东西,如图片音视频,压缩之后仍可以使用但影响体验的,可以使用有损压缩
  • 有损压缩无法恢复,不属于编码

*序列化

  • 序列化: 把数据对象(一般是内存中的,例如JVM 中的对象)转换成字节序列的过程
  • 反序列化: 把字节序列重新转换成内存中的对象

目的
让内存中的对象可以被存储和传输

序列化是编码么
严格意义上讲,序列化不是编码

*Hash

定义:把任意数据转换成指定大小范围(通常很小)的数据

作用

摘要、数字指纹

经典算法

MD5,SHA1,SHA256等

  • 好的哈希算法应该避免哈希碰撞
    • 如下 haha和hehe的哈希值都是4, 产生了哈希碰撞
      public int dshHash(String source){
          return source.length();
      }
      
      dshHash("moneyiloveu!") = 12;
      dshHash("haha") = 4;
      dshHash("hehe") = 4;
      
  • 同理:好的哈希算法应该能够防破解,及不能通过哈希值找到源数据

实际用途

  • 数据完整性验证
  • 身份的快速匹配
  • 快速查找:hashCode()和HashMap
    • 重写equals也要重写hashCode:
      • 例如hashMap初步判断相等用的是hashCode,因为hashCode计算速度很快,这样就可以简单快速判断相等;
      • 如果hashCode相等,就会用equals判断相等性
      • 使hashSet等容器效率更高
      • 通常情况下:如果equals为true那么hashcode是一定相等的
      • 如果重写了equals而没有重写hashcode,hashmap会认为这是两个不相等的对象,这样就会导致bug的产生
    public class Example{
        String name;
        int age;
        
        @Override
        public boolean equals(Object o){
            return age == o.age && name.equals(o.name);
        }
        
        @Override 
        public int hashCode() {
            return age*10000+name.length();
        }
        
    }
    
  • 隐私保护
    用户注册输入 name:willA
    用户注册输入 password:123456 -> 服务端SHA1(123456) = qw$%^1 -> 存储在数据库
    
    //服务端并没有存储明文密码,所以一般只提供找回密码功能,而不会像十多年前那样提供密码找回功能
    
    用户登录输入 password:123456 -> 服务端SHA1(123456) == qw$%^1 -> 是willA,登录成功
    
    
    • 彩虹表:密码和哈希值做映射的表叫做彩虹表,一般常用的哈希值可以通过彩虹表查询到原密码,所以很多网站会加点盐
    SHA1 (111111)  == ksjlkj
    SHA1 (123456)  == awefid
    SHA1 (888888)  == mcv82k
    
    • 加盐
    123456 -> SHA1(123456abc) = iouhjy
    

Hash是编码么?

不是
hash是完全不可逆的,无法逆向转换,因为信息损耗很大

Hash是加密么?据说MD5是[不可逆加密]?

不是

  • 很遗憾,百度百科是错的
  • 加密是可以还原的,MD5不可以还原

签名与验证(完整版)

*字符集

一个由整数向现实世界中的文字符号的 Map

分支

  • ASCII: 128 个字符,1字节
  • IS0-8859-1:对ASCII进行扩充,1字节
  • Unicode: 13 万个字符,多字节
    • UTF-8 : Unicode 的编码分支
    • UTF-16: Unicode 的编码分支
  • GBK/GB2312/GB18030: 中国自研标准,多字节,字符集