最近在项目中用到了一些加密算法来对密码进行加密,记录项目中思考的一些问题:
- Java中字符串到字节数组是怎么转换的?
将字符串中的每一个字符转换成对应的ISO-8859-1码表中的编码
- ASCII码表里的字符总共有多少个?
0~255共256个。前128个为常用的字符(运算符,字母,数字等键盘上可以显示的)为标准的ASCII码共7位,后128个为特殊字符是键盘上找不到的,是扩充的ASCII码共8位。一些常用的对应关系如下:0 --> 48,A --> 65,a --> 97
- 常见的码表
- ASCII码表:每个字符占用一个字节,共128个常用字符映射
- GB2312码表:兼容ASCII码表,英文大小写字母,数字,美式标点符号占一个字节,中文占两个字节,中文的每个字节都是负数(也就是每个字节的最高位都是1,因此每个字节变化的只有7位),因此共有128 * 128 = 16384 个字符映射关系
- GBK / GB18030:兼容GB2312码表,英文数字美式符号仍占一个字节,中文占两个字节,但是第一个字节只能为负数(变化的位数有7位),第二个字节既可以是正数也可以是负数(也就是变化的位数有8位),因此共有128 * 256 = 32768个字符映射关系
- Unicode码表:每个字符都占两个字节,每个字节既可以为正数也可以是负数,因此共有65536种字符映射关系
- UTF-8:英文占1个字节,中文均占3个字节
- 对称加密和非对称加密的区别?
- 对称加密:使用同一把密钥(公钥)来加密和解密数据,并且公钥需在网络上传播,不安全,但是由于加密和解密使用同样的密钥,所以速度快。
- 非对称加密:使用一对密钥(公钥和私钥)来加密和解密数据,私钥只能由一方来安全保管,公钥可以在网络上传播。非对称加密使用这对密钥中的一个来进行加密,另一个来进行解密,由于解密的密钥不需要通过网络发送,所以安全性大大提高,但是由于加密和解密使用不同的密钥,所以速度慢。
- 现实是如何对称加密和非对称加密结合起来使用的呢?
为了保证数据的传输速率,还是要通过对称加密来进行传送数据,但是同时为了保证对称加密密钥的安全性,通过非对称加密来加密**“对称加密的密钥”,这样在数据到达另一方的时候,对方就可以通过非对称加密的另一把密钥来对“对称加密的密钥”进行解密,进而拿到“对称加密的密钥”,从而对数据进行解密。因为“对称加密的密钥”长度一般比较短,所以加密解密它的时间不会太长,但因为对它加了密,所以它在网络上就能安全传输,这样就可以使数据安全快速**的传输到另一方。
- 什么是Hex编码?
将字节数组数据转换成字符数组数据,将一个字节转换成两个字符
- Hex是如何将一个字节转换为两个字符的呢?源码如下:
protected static char[] encodeHex(final byte[] data, final char[] toDigits) { final int l = data.length; // 创建一个二倍于原数组大小的数组。左移一位代替乘2操作 final char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { // toDigits的字符组成:0~f(lower) 0~F(upper) out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return out; }
- Hex解码过程:
public static byte[] decodeHex(final char[] data) throws DecoderException { final int len = data.length; // 判断奇偶 if ((len & 0x01) != 0) { throw new DecoderException("Odd number of characters."); } final byte[] out = new byte[len >> 1]; // two characters form the hex value. for (int i = 0, j = 0; j < len; i++) { int f = toDigit(data[j], j) << 4; j++; f = f | toDigit(data[j], j); j++; out[i] = (byte) (f & 0xFF); } return out;
}
```