哈希(Hash)与加密(Encrypt)的区别
哈希是将目标文本转换成固定长度,不可逆的消息摘要
加密是将目标文本转换成具有不同长度,可逆的密文。
选择:
需要还原成明文的选用加密,不需要的话,使用Hash。
密码可以使用哈希, 密码忘记,重置密码。
哈希算法
Hashing 哈希法、散列法。
哈希算法有很多: 常见的有 MD5、SHA1
MD5,全称Message-Digest Algorithm 5, MD5之前有MD2、MD3和MD4
SHA-1 广泛使用在TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为MD5的后继者。
SHA-2,包括SHA-224、SHA-256、SHA-384和SHA-512.
SHA-3, 曾被称为Keccak算法。
RIPEMD-160。
Java MessageDigest实现 MD5
MD5计算出128比特位,也就是长度是16的字节数组。
MD5的加密后是长度32的字符串, 长度16的字节数组要产生长度32的字符,则每个字节元素要转换位两个字符。
加密代码如下:
public static String encrypt(String str) {
String encryptStr = null;
try {
byte[] bytes = MessageDigest.getInstance("MD5").digest(str.getBytes()); //长度16的字节数组
StringBuffer buffer = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) { //每个循环产生2个字符
if (((int) bytes[i] & 0xff) < 0x10) buffer.append("0"); //小于16, 只有一位,则补0
buffer.append(Long.toString((int) bytes[i] & 0xff, 16)); //int 32bit, 使用&, 高24位置0
}
encryptStr = buffer.toString();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return encryptStr;
}
说明:
- MessageDigest.getInstance(“MD5”).digest()用于加密
- 因为int是4个字节, 与0xff按位与的目的是高24位置为0.
- < 0x10 ,也就是小于10进制16的时候, 就只有一个字符, 此时补一个0。
备注
- byte[] bytes = MessageDigest.getInstance(“MD5”).digest(str.getBytes()); 也可以使用以下写法:
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte[] bytes = md.digest();
Long.toString((int) bytes[i] & 0xff, 16)
也可以使用
buffer.append(Long.toHexString((int) bytes[i] & 0xff));
或是
buffer.append(Integer.toHexString((int) bytes[i] & 0xff));
Long.toString(long i, int radix)
radix - 进制数
int i = 1;
String str = Long.toString(i,16);
Assert.assertTrue(str.equals("1"));
i = 20;
str = Long.toString(i,16);
Assert.assertTrue(str.equals("14"));//1*16+4 = 20
i=200;
str = Long.toString(i,16);
Assert.assertTrue(str.equals("c8"));//12*16+8 = 20
实例代码:
https://github.com/osxm/jcodef/blob/master/jcodef-func/src/main/java/cn/osxm/jcodef/func/bit/BitTests.java