URL编码算法
URL编码的出现是出于兼容性的考虑,由于很多 服务器只识别ASCII字符,当包含中文这种非ASCII码时,如果字符是 A ~ Z ,a ~ zjava中md5解密代码, 0 ~ 9 以及 - 、 _ 、 . 、 * ,则保持不变; 如果是其他字符,先转换为 UTF-8 编码,然后对每个字节以 %XX 表示。
以下是基于URL编码算法的编码与解码,需要注意的是编码与解码时字符编码集应当设置为UTF-8
public class Demo01 {
public static void main(String[] args) throws UnsupportedEncodingException {
//编码
String url = "https://www.baidu.com/s";
String result = "语雀";
String encode = URLEncoder.encode(result, "utf-8");
System.out.println(encode);
System.out.println(url+"?wd="+encode);
//解码
String param = "https://www.baidu.com/s?wd=%E6%88%91%E6%9C%AC%E5%B0%86%E5%BF%83%E5%90%91%E6%98%8E%E6%9C%88";
String content = URLDecoder.decode(param, "utf-8");
System.out.println(content);
}
}
编码算法
编码可以把任意长度的二进制数据变为纯文本(在java中二进制数据为byte数组),并且纯文本内容中且只包含指定字符内 容: A ~ Z 、 a ~ z 、 0 ~ 9 、 + 、 / 、 = 。它的原理是把 3 字节的二进制数据按 6bit 一组,用 4 个int整数表示,然后查表, 把 int 整数用索引对应到字符,得到编码后的字符串。 6 位整数的范围总是 0 ~ 63 ,所以,能用 64 个字符表示:字符 A ~ Z 对应索引 0 ~ 25 ,字符 a ~ z 对应索引 26 ~ 51 ,字符 0 ~ 9 对应索引 52 ~ 61 ,最后两个索引 62 、 63 分别用字符 + 和 / 表示。
以下是基于编码算法的编码与解码
public class Demo02 {
public static void main(String[] args) throws IOException {
byte[] imagebyteArray = Files.readAllBytes
(Paths.get("D:\\tupian11\\douban\\珠峰队长.jpg"));
//读取本地图片并且保存在byte数组里
String imageData= Base64.getEncoder().
encodeToString(imagebyteArray);
//将图片以BASE64编码方式进行编码
byte[] imageResultArray = Base64.getDecoder()
.decode(imageData);
//将图片以BASE64编码方式进行解码
<p>
Files.write(Paths.get("D:\\tupian12\\你的队长.jpg"),
imageResultArray);
//将解码得到的保存在byte字节数组,并且写入指定目录
}
</p>
小结
URL 编码和 编码都是编码算法,它们不是加密算法; URL 编码的目的是把任意文本数据编码为 % 前缀表示的文本,便于浏览器和服务器处理; 编码的目的是把任意二进制数据编码为文本,但编码后数据量会增加 1/3 。
哈希算法(加密)
什么是哈希算法呢?好像熟悉又陌生
哈希算法( Hash )又称摘要算法( ),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算 法的目的:为了验证原始数据是否被篡改。
而哈希算法的特点在于: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。
我们可以知道 :根据碰撞概率java中md5解密代码 Java中的编码算法与常用的加密算法,哈希算法的输出长度越长,就越难产生碰撞java中md5解密代码,也就越安全。
常用的Hash算法
算法
输出长度(位)
输出长度(字节)
MD5
128 bits
16 bytes
SHA-1
160 bits
20 bytes
-160
160 bits
20 bytes
SHA-256
256 bits
32 bytes
SHA-512
512 bits
64 bytes
MD5算法:
在使用 时,我们首先根据哈希算法获取一个 实例,然后,反复调用 (byte[]) 输入数据。当输入结束后,调用 () 方法获得 byte[] 数组表示的摘要,最后,把它转换为十六进制的字符串。以下代码我们以MD5算法为例。
public class Demo06 {
public static void main(String[] args) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update("天青色等烟雨".getBytes());
md5.update("而我在等你".getBytes());
byte[] resultArray=md5.digest();
System.out.println(Arrays.toString(resultArray));
md5.update("天青色等烟雨而我在等你".getBytes());
byte[] resltArray2=md5.digest();
System.out.println(Arrays.toString(resltArray2));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SHA-1算法:
SHA-1 也是一种哈希算法,它的输出是 160 bits ,即 20 字节。 SHA-1 是由美国国家安全局开发的, SHA 算法实际上是一个系列,包括 SHA-0 (已废弃)、 SHA-1 、 SHA-256 、 SHA-512 等。 在 Java 中使用 SHA-1 ,和 MD5 完全一样,只需要把算法名称改为" SHA-1 ":
public class main {
public static void main(String[] args) {
// 创建一个MessageDigest实例:
MessageDigest md = MessageDigest.getInstance("SHA-1");
// 反复调用update输入数据:
md.update("天青色等烟雨".getBytes("UTF-8"));
md.update("而我在等你".getBytes("UTF-8"));
// 20 bytes: db8ac1c259eb89d4a131b253bacfca5f319d54f2
byte[] results = md.digest();
StringBuilder sb = new StringBuilder();
for(byte bite : results) {
sb.append(String.format("x", bite));
}
System.out.println(sb.toString());
<p>![md5解密算法java_java md5解密代码_java中md5解密代码][2]
}
</p>
Hmac加密算法
Hmac 算法就是一种基于密钥的消息认证码算法,它的全称是 Hash-based Code ,是一种更安全的消息 摘要算法。
Hmac 算法总是和某种哈希算法配合起来用的。
例如,我们使用 MD5 算法,对应的就是 Hmac MD5 算法,它相当于“加盐” 的 MD5 : ≈ md5(, input)
因此, 可以看作带有一个安全的 key 的 MD5 。使用 而不是用 MD5 加 salt ,有如下好处:
使用的 key 长度是 64 字节,更安全;
Hmac 是标准算法,同样适用于 SHA-1 等其他哈希算法;
Hmac 输出和原有的哈希算法长度一致。
可见, Hmac 本质上就是把 key 混入摘要的算法。
验证此哈希时,除了原始的输入数据,还要提供 key 。
为了保证安全,我们不会自 己指定 key ,而是通过 Java 标准库的 生成一个安全的随机的 key 。
public class Demo10 {
public static void main(String[] args) {
String str = "mlmdxbldm";
try {
KeyGenerator kg = KeyGenerator.getInstance("HmacMD5");
SecretKey key = kg.generateKey();
byte[] keyByteArray = key.getEncoded();
StringBuilder sb = new StringBuilder();
for(byte b : keyByteArray) {
sb.append(String.format("X", b));
}
System.out.println(Arrays.toString(keyByteArray));
System.out.println("密钥为"+sb);
System.out.println("密钥长度为"+keyByteArray.length);
System.out.println("密钥字节数为"+sb.length());
//使用秘钥
Mac mac = Mac.getInstance("HmacMD5");
//初始化
mac.init(key);
//加密
mac.update(str.getBytes());
<p>![java md5解密代码_md5解密算法java_java中md5解密代码][3]
//
byte[] result = mac.doFinal();
StringBuilder sb1 = new StringBuilder();
for(byte b : result) {
sb1.append(String.format("X", b));
}
System.out.println("加密结果"+sb1);
System.out.println("加密结果长度"+sb1.length());
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
</p>
和 MD5 相比,使用 的步骤是:
1. 通过名称 获取 实例;
2. 通过 创建一个 实例;
3. 通过名称 获取 Mac 实例;
4. 用 初始化Mac实例;
5. 对 Mac 实例反复调用 (byte[]) 输入数据;
6. 调用 Mac 实例的 () 获取最终的哈希值。
如果我们想恢复并且验证,其中new 则是恢复密钥时传入数组的代码。
package com.my.hyz.homework;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
<p>
public class Demo11 {
public static void main(String[] args) {
String str = "mlmdxbldm";
try {
byte[] keyByteArray = {78, -100, -109, 29, 87, -46, -77, -36, 2, -2, -103, -22, 45, -97, -70, 60, 102, 120, -21, 0, 79, 97, 111,
23, 38, 39, -110, 7, 102, 6, -101, 105, -6, -87, 114,
21, -82, 10, -119, -81, -57, 95, 95, -7, -97, -87, 79,
-25, -87, -63, 65, -127, -90, -85, 75, 37, -36, -107,
114, 64, 40, 111, -86, -24};
SecretKey key = new SecretKeySpec(keyByteArray, "HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
//初始化
mac.init(key);
//加密
mac.update(str.getBytes());
//
byte[] result = mac.doFinal();
StringBuilder sb1 = new StringBuilder();
for(byte b : result) {
sb1.append(String.format("X", b));
}
System.out.println("加密结果"+sb1);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
</p>
文章来源:https://blog.csdn.net/m0_66605858/article/details/125878703