补充知识点:
字节:也就是 byte 是一种统计单位,表示数量的多少
字符:是指计算机中使用的文字和符号,比如:1、2、3、A、S、D、$、%等等符号
字节与字符的对应关系:它们完全不是一个概念,所以,没有什么有没有区别这个说法。不同的编码,两者的对应关系是不相同的,我这里就说常用的两种编码:
- ASCII码中,一个英文字母(不区分大小写)占一个字节,一个中文汉字占两个字节
- UTF-8中,一个英文字母占一个字节,一个中文汉字占三个字节
我们加密最终常常操作的是bit,而我们加密首先得到的是byte数组的,byte的取值范围-128~127,中间包括0,刚好256个。也就是2^8=256。并且,1 byte = 8 bit(1kb = 1024 byte = 8^1024 bit等等)
我们获得了byte之后,要把byte数组转成String字符串,String其实就是char数组,我们java有一个new String(char[] chars),应该都用过。我们转成字符串的前提是转成char数组,由于,1 char = 2 byte,所以,我们byte转成char长度扩大了1倍。
四种分类
- MD5加密
- Base64加密
- 对称加密
- 非对称加密
MD5加密——不可逆
概念
MD5加密是我们常见的加密算法,是不可逆的,也就是说加密完成之后,无法解密转成原来的内容。MD5加密算法其实是一种散列函数,使用的是hash算法。MD5的原文是无线多个,但是MD5的值是有限的。所以一个MD5的值可能对应多个原文。SHA算法跟MD5是差不多的,只是MD5是128位,SHA是160位,多32位
为什么MD5的值是有限多个呢?主流的MD5使用的是将任意长度的字节串映射为一个128bit的大整数。也就是一共有2^128种可能,所以说这个数字是有限的,而,我们的原文则是无限多个。发现两段原文对应同一个MD5的值概率非常小,也就忽略不记了。
使用
1 | String name1 = "haichenyi"; |
我们通过MD5,得到的是一个byte数组(这个byte数组的长度跟我们的1byte=8bit没有直接关系),我们需要做的就是对这个byte数组进行操作,我们习惯上就是把这个btye转成16进制数存进数据库,当然,你也可以转成其他的类型存到数据库。这里给出几个byte数组转16进制字符串的方法,亲测可用:
1 | private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', |
Base64加密——可逆
流程
- 要知道的是有一个64个数的表,也称Base64编码表。可以字节定义,不过都是用的一样的。
- Base64是按照字符长度,以3个字符为一组
- 接着增对每组的每个字符,取ASCII编码
- 然后将获得的编码转换成8bit的二进制,就会得到3*8=24bit的字节
- 然后将这24bit的字节以6个bit为一组,分成4组
- 接着在每组前面填两个高位0,凑成每组8bit
- 最后将这每组8bit的二进制转成十进制,对应下面的Base64编码表
Base64 编码表
value | char | value | char | value | char | value | char |
---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w |
1 | B | 17 | R | 33 | h | 49 | x |
2 | C | 18 | S | 34 | i | 50 | y |
3 | D | 19 | T | 35 | j | 51 | z |
4 | E | 20 | U | 36 | k | 52 | 0 |
5 | F | 21 | V | 37 | l | 53 | 1 |
6 | G | 22 | U | 38 | m | 54 | 2 |
7 | H | 23 | X | 39 | n | 55 | 3 |
8 | I | 24 | Y | 40 | o | 56 | 4 |
9 | J | 25 | Z | 41 | p | 57 | 5 |
10 | K | 26 | a | 42 | q | 58 | 6 |
11 | L | 27 | b | 43 | r | 59 | 7 |
12 | M | 28 | c | 44 | s | 60 | 8 |
13 | N | 29 | d | 45 | t | 61 | 9 |
14 | O | 30 | e | 46 | u | 62 | + |
15 | P | 31 | f | 47 | v | 63 | / |
使用
1 | String str = "hai"; |
解析
这里,我要使用Base64加密”hai”这个字符串,根据上面的流程:
待加密字符串 | h | a | i |
---|---|---|---|
ASCII编码 | 104 | 97 | 105 |
二进制 | 01101000 | 01100001 | 01101001 |
下面,上面的表不好表示,我再换一个表,下一步,该6位分一组了
现在的字符串:01101000 01100001 01101001
六位分一组 | 011010 | 000110 | 000101 | 101001 |
---|---|---|---|---|
每组前面补0 | 00011010 | 00000110 | 00000101 | 00101001 |
转成10进制 | 26 | 6 | 5 | 41 |
Base64编码 | a | G | F | p |
结果图:
PS:
- Base64.encodeToString()方法直接转成加密后的字符串
- Base64.encode()方法返回的byte数组是16进制的,不用手动在去转一遍16进制