【位操作的程序实例】Base64编码器及其简单实现【位运算】

Java 8 中Base64编码已经成为Java标准类库的一部分,并内置了Base64编码的编码器和解码器。Base64工具类提供了一套静态方法获取三种BASE64的编码和解码器:标准、URL、MIME。

由于很多信息的编码是无法直接打印的。Base64编码要求把每三个8Bit的字节转换为四个6Bit的字节,然后把6Bit再添加两位高位0,组成四个8Bit的字节,转换后字符串将是初始长度的4/3倍。经Base64处理后,不可显示的乱码信息(如密文)就可以打印出来(不过打印信息主要是用于展示,但并不适用于人类阅读)。
Base64编码的其他规则:
1,把3个字节变成4个字节;
2,每76个字符加一个换行符;
3,最后的结束符也要处理。

标准的Base64编码不适合直接放在URL里传输,因为URL编码器会把标准Base64编码中的“/”和“+”字符转换成形如“%XX”的形式,而“%”号在保存到数据库时还需要进行转换,因为在SQL查询语言中“%”号是通配符。
为了解决此问题产生了一个改正版本的Base64编码,改正措施是末尾填充“=”,并将标准Base64编码中的“+”和“/”分别用“-”和“_”代替。

为了更好地理解Base64编码,下面提供一个简单的Base64编码器实现程序:

import java.io.ByteArrayOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Base64OutputStream extends FilterOutputStream{
	private static char[] toBase64 = { 'A','B','C','D','E','F','G','H','I','J',
			'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
			'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
			'0','1','2','3','4','5','6','7','8','9','+','/' };
	private int col = 0;
	private int i = 0;
	private int[] inbuf = new int[3];
	
	public static String base64Encode(String str) 
	{ //把普通String字符串转换成Base编码的字符串
		ByteArrayOutputStream bOut = new ByteArrayOutputStream();
		Base64OutputStream out = new Base64OutputStream(bOut);
		try {
			out.write(str.getBytes());
			out.flush();
		} catch (IOException e) { e.printStackTrace();	}
		return bOut.toString();
	}
	

	public Base64OutputStream(OutputStream out) {
		super(out);
	}
	@Override
	public void flush() throws IOException {
		if (i>0&&col>=76) {  
			super.write('\n');
			col = 0;
		}
		if (i==1) {  //inbuf[1]是最后一个字节
			super.write(toBase64[(inbuf[0]&0xFC)>>2]);
			super.write(toBase64[(inbuf[0]&0x03)<<4]);
			super.write('=');
			super.write('=');
		} else if (i==2) {   //inbuf[2]是最后一个字节
			super.write(toBase64[(inbuf[0]&0xFC)>>2]);
			super.write(toBase64[((inbuf[0]&0x03)<<4)|((inbuf[1]&0xF0)>>4)]);
			super.write(toBase64[(inbuf[1]&0x0F)<<2]);
			super.write('=');
		}
	}
	@Override
	public void write(int c) throws IOException {
		inbuf[i++] = c;
		if (i==3) {
			if (col>=76) {
				super.write('\n');
				col = 0;
			}
			super.write(toBase64[(inbuf[0]&0xFC)>>2]);
			super.write(toBase64[((inbuf[0]&0x03)<<4)|((inbuf[1]&0xF0)>>4)]);
			super.write(toBase64[((inbuf[1]&0x0F)<<2)|((inbuf[2]&0xC0)>>6)]);
			super.write(toBase64[inbuf[2]&0x3F]);
			col += 4;
			i = 0;
		}
	}
	
	public static void main(String[] args) {
		final String[] text = {"珍禽栩栩枝间舞",
				"满园花发艳无双",
				"丰姿挺秀鲜似锦",
				"群芳岂肯妒天香"};
		String encoded = null ;
		for (int i = 0; i < text.length; i++) {
			encoded = base64Encode(text[i]);
			System.out.println( encoded );
		}
	}
}

程序的运行效果图:
在这里插入图片描述
程序说明:
我们在测试时使用了普通的可显示文本作为输入参数。实际上,Base64编码器的使用场景并不是给普通可显示文本进行编码,而是把不可显示的文本信息进行编码,从而变成可显示和打印的文本。有一个使用场景是对普通的可显示文本进行加密后,其密文通常无法正常显示和打印,此时用Base64编码器处理后,就可把密文显示或打印出来。打印出来的信息也是加密的。

Java 8 中Base64编码已经成为Java标准类库的一部分,并内置了Base64编码的编码器和解码器。
我们也顺便来演示一下JDK8中自带的Base64编码的编码器和解码器用法,测试程序如下:

import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Base64Test {

	public static void main(String[] args) {
		final String[] text = {"珍禽栩栩枝间舞",
				"满园花发艳无双",
				"丰姿挺秀鲜似锦",
				"群芳岂肯妒天香"};
		String[] encoded = {null,null,null,null};
		System.out.println( "编码后的Base64编码文本:" );
		for (int i = 0; i < text.length; i++) {
			encoded[i]  = Base64.getEncoder().encodeToString( text[i].getBytes( StandardCharsets.UTF_8 ) );
			System.out.println( encoded[i] );
		}

		System.out.println( "解码后变成原文:" );
		String decoded;
		for (int i = 0; i < encoded.length; i++) {
			decoded = new String( Base64.getDecoder().decode( encoded[i] ), StandardCharsets.UTF_8 );
			System.out.println( decoded );
		}
	}
}

其测试效果图,如下图所示:
在这里插入图片描述
说明:
Java 8 中Base64编码器的算法与我们前文自编的Base64编码器有差异,所以,编码后的Base64编码文本并不一致。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值