基本的编码算法总结(上)

ASCII:只支持全英文;
JBK:支持全中文。
**URL编码:**是浏览器发送数据给服务器时使用的编码,它通常附加在URL的参数部分。

Base64编码

 Base64编码就是把任意长度的二进制数据(Byte[] 数组)变为纯文本。

实例代码:
包含编码和解码:

//从文本文件中读取一张图片的Base64编码值
		List<String> lines = Files.readAllLines(Paths.get("E:\\音乐\\img\\周杰伦.txt"));//括号里的就是一组Byte[]数组
		StringBuilder sb = new StringBuilder();
		for(String In:lines) {
			sb.append(In);
		}
		System.out.println(sb.length());
		
		//Base解码
		byte[] imageByteArray = Base64.getDecoder().decode(sb.toString());
		Files.write(Paths.get("E:\\音乐\\img\\zhou.jpg"),imageByteArray);

由于标准的Base64编码会出现+ 、/、=。所以是不适合把Base64编码后的字符放入URL中。

 // 原始字节内容
		byte[] input = new byte[] { 0x01, 0x02, 0x7f, 0x00 };
		
		// 分别使用两种方式进行编码
		String b64Encode = Base64.getEncoder().encodeToString(input);
        String b64UrlEncoded = Base64.getUrlEncoder().encodeToString(input);
        
        // 结果完全一致
        System.out.println(b64Encode); 
        System.out.println(b64UrlEncoded);
        
        // 分别使用两种方式进行重新解码
        byte[] output1 = Base64.getDecoder().decode(b64Encode);
        System.out.println(Arrays.toString(output1));
        
        byte[] output2 = Base64.getUrlDecoder().decode(b64UrlEncoded);
        System.out.println(Arrays.toString(output2));

但是使用Base64编码时,它的传输效率特别低,尤其是字符越少的情况下。因为他会把原始数据长度增加1/3。

URL编码

URL的编码:
实例代码:

String content = "我本将心向明月";
		String result = Base64.getEncoder().encodeToString(content.getBytes());
		System.out.println(result);

URL的解码:
代码实例:

String value = "ztKxvr2r0MTP8sP31MI=";
		byte[] param = Base64.getDecoder().decode(value);
		System.out.println(param);

哈希算法

哈希算法又叫摘要算法。
它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。
哈希算法的目的:为了验证原始数据是否被篡改。
哈希算法的特点是:1、相同的输入一定得到相同的输出;
2、不同的输入 大概率得到不同的输出。

哈希碰撞
是指两个不同的输入得到了相同的输出。

"AaAaAa".hashCode(); // 0x7460e8c0
"BBAaBB".hashCode(); // 0x7460e8c0

"通话".hashCode(); // 0x11ff03
"重地".hashCode(); // 0x11ff03

碰撞时不能避免的,因为输出的字节长度是固定的,String和hashcode()输出的是4个字节整数,最多只有4294967296种输出,单数输入的数据长度是不固定的,有无数种输入可能。

MD5算法

Java标准库提供了常用的哈希算法,并且由一套统一的接口。

import java.security.MessageDigest;

public class main {
	public static void main(String[] args)  {
		// 创建一个MessageDigest实例:
        MessageDigest md = MessageDigest.getInstance("MD5");
       
        // 反复调用update输入数据:
        md.update("Hello".getBytes("UTF-8"));
        md.update("World".getBytes("UTF-8"));
        
        // 16 bytes: 68e109f0f40ca72a15e05cc22786f8e6
        byte[] results = md.digest(); 

        StringBuilder sb = new StringBuilder();
        for(byte bite : results) {
        	sb.append(String.format("%02x", bite));
        }
        
        System.out.println(sb.toString());
	}
}

SHA-1算法

在Java中使用SHA-1,和MD5完全一样,只需要把算法名称改为”SHA-1“。

import java.security.MessageDigest;

public class main {
	public static void main(String[] args)  {
		// 创建一个MessageDigest实例:
        MessageDigest md = MessageDigest.getInstance("SHA-1");
       
        // 反复调用update输入数据:
        md.update("Hello".getBytes("UTF-8"));
        md.update("World".getBytes("UTF-8"));
        
        // 20 bytes: db8ac1c259eb89d4a131b253bacfca5f319d54f2
        byte[] results = md.digest(); 

        StringBuilder sb = new StringBuilder();
        for(byte bite : results) {
        	sb.append(String.format("%02x", bite));
        }
        
        System.out.println(sb.toString());
	}
}

哈希算法的用途:
1、校验下载文件
2、存储用户密码

Hmac编码

在存储用户的哈希口令时,要加盐存储,目的就在于抵御彩虹表。
而Hmac算法就是一种基于密钥的消息认证码算法,是一种更安全的信息摘要算法。
Hmac算法总是和某种哈希算法配合使用。MD5算法会“加盐”。而HmacMD5算法可以看作带有一个安全的key的MD5.
HmacMD5而不是用MD5加salt,有如下好处:

     1、HmacMD5使用的key长度是64字节,更安全;
     2、Hmac是标准算法,同样适用于SHA-1等其他哈希算法。
    3、 Hmac输出和原有的哈希算法长度一致。

因此,HmacMD5本质上就是把key混入摘要的算法。HmacMD5中的key是Java标准库KeyGenerator生成一个随机安全的key。
代码示例:

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;

public class main {
	public static void main(String[] args) throws NoSuchAlgorithmException, IllegalStateException, UnsupportedEncodingException, InvalidKeyException {
        
        // 获取HmacMD5秘钥生成器
		KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
		
        // 产生秘钥
        SecretKey secreKey = keyGen.generateKey();
        
        // 打印随机生成的秘钥:
        byte[] keyArray = secreKey.getEncoded();
        StringBuilder key = new StringBuilder();
        for(byte bite:keyArray) {
        	key.append(String.format("%02x", bite));
        }
        System.out.println(key);
        
        // 使用HmacMD5加密
        Mac mac = Mac.getInstance("HmacMD5");
        mac.init(secreKey); // 初始化秘钥
        mac.update("HelloWorld".getBytes("UTF-8"));
        byte[] resultArray = mac.doFinal();
        
        StringBuilder result = new StringBuilder();
        for(byte bite:resultArray) {
        	result.append(String.format("%02x", bite));
        }
        System.out.println(result);
	}
}

和MD5相比,使用HmacMD5的步骤数是:

 1、通过名称HmacMD5获取KeyGenrator对象;
 2、通过KeyGenerator创建一个SecreKey实例;
 3、通过名称HmacMD5获取Mac实例;
 4、用SecreKey初始化Mac实例;
 5、对Mac实例反复调用update(byte[])输入数据;
 6、调用Mac实例的doFinal()获取最终的哈希值。

有了Hmac计算的哈希和SecreKey,但是SecreKey不能从KeyGenerstor生成,而是从一个byte[]数组恢复:
代码示例:

byte[] keyArray = {70, 31, 31, 113, -75, 45, 5, 112, -32, -32, 57, 59, -77, -52, -22, -67, -115, -15, -32, -57, 94, -78, 58, -115, 76, -104, 41, -120, -21, 28, 123, -13, -79, -17, 18, 63, -45, -14, -43, -33, -126, -115, 76, -87, -123, -16, -109, -127, -113, -114, 19, 96, 69, 73, -2, -75, -66, -88, -10, -9, -14, 104, -97, -69};
		
SecretKey secreKey = new SecretKeySpec(keyArray, "HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(secreKey); // 初始化key
mac.update("HelloWorld".getBytes("UTF-8"));
byte[] resultArray = mac.doFinal();

StringBuilder result = new StringBuilder();
for(byte bite:resultArray) {
    result.append(String.format("%02x", bite));
}
System.out.println(result);
  • 17
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值