`
sure
  • 浏览: 10984 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用重排的编码表,实现Base64编码/解码

阅读更多
Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME, 在XML中存储复杂数据.

public class Base64Util {
	private static final int ENCODE_BLOCK=4;
	private static final int UNENCODE_BLOCK=3;
	private static final byte DEFAULTF_PAD='=';
	private static final byte[] ENCODE_TABLE={
		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98,
		99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
		109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 
		119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72,
		73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 
		86, 87, 88, 89, 90, 33, 45
	};
	private static final byte DECODE_TABLE[]={
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, 
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, -1, -1, 0, 1, 2, 3, 
		4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 36, 37, 38, 39, 40, 41,
		42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
		60, 61, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
		20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, 
		-1, -1, -1, -1
	 };
	public static String encode(String str){
		if(str==null||str.length()==0) return null;
		try {
			return encode(str.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}
	public static String encode(byte[] b) throws UnsupportedEncodingException{
		if(b==null||b.length==0) return null;
		int modulus = b.length%3;
		int len = getEncodeLength(b);
		byte bytes[] = new byte[len];
		int loop= b.length - modulus;
		int b1,b2,b3;
		for(int i=0,j=0;i<loop;){
			b1 = b[i++] & 255;//0xFF
			b2 = b[i++] & 255;
			b3 = b[i++] & 255;
			bytes[j++] = ENCODE_TABLE[(b1 >>> 2) & 63];
			bytes[j++] = ENCODE_TABLE[((b1 << 4) | (b2 >>> 4)) & 0x3f];
			bytes[j++] = ENCODE_TABLE[((b2 << 2) | (b3 >>> 6)) & 0x3f];
			bytes[j++] = ENCODE_TABLE[b3 & 0x3f];
		}
		if(modulus == 1){
			b1 = b[b.length-1] & 0xff;
			bytes[bytes.length-4] = ENCODE_TABLE[(b1 >>> 2) & 0x3f];
			bytes[bytes.length-3] = ENCODE_TABLE[(b1 << 4) & 0x3f];
			bytes[bytes.length-2] = DEFAULTF_PAD;
			bytes[bytes.length-1] = DEFAULTF_PAD;
		}
		if(modulus == 2){
			b1=b[b.length-2] & 0xff;
			b2=b[b.length-1] & 0xff;
			bytes[bytes.length-4] = ENCODE_TABLE[(b1 >>> 2) & 0x3f];
			bytes[bytes.length-3] = ENCODE_TABLE[((b1 << 4) | (b2 >> 4)) & 0x3f];
			bytes[bytes.length-2] = ENCODE_TABLE[(b2 << 2) & 0x3f];
			bytes[bytes.length-1] = DEFAULTF_PAD;
		}
		return new String(bytes,"UTF-8");
	}
	public static String decode(String str) throws UnsupportedEncodingException{
		if(str==null||str.length()==0) return str;
		 return decode(str.getBytes("UTF-8"));
	}
	public static String decode(byte[] b) throws UnsupportedEncodingException{
		byte[] bytes;
		int b1, b2, b3, b4;
		if(b == null || b.length == 0) return "";
		int len=b.length;
		int resultLength=getDecodeLength(b);
		bytes=new byte[resultLength];
		for(int i = 0, j = 0;i < len-4;){
			b1 = DECODE_TABLE [b[i++]];
			b2 = DECODE_TABLE [b[i++]];
			b3 = DECODE_TABLE [b[i++]];
			b4 = DECODE_TABLE [b[i++]];
			bytes[j++] = (byte)((b1 << 2) | (b2 >> 4));
			bytes[j++] = (byte)((b2 << 4) | (b3 >> 2));
			bytes[j++] = (byte)((b3 << 6) | b4);
		}
		if( b[len-2] == DEFAULTF_PAD){//means modulus=1
			b1 = DECODE_TABLE [b [len - 4]];
			b2 = DECODE_TABLE [b [len - 3]];
			bytes[resultLength - 1] =  (byte)((b1 << 2) | (b2 >> 4));
		}else if(b[len-1] == DEFAULTF_PAD){//means modulus=2
			b1 = DECODE_TABLE [b [len - 4]];
			b2 = DECODE_TABLE [b [len - 3]];
			b3 = DECODE_TABLE [b [len - 2]];
			bytes[resultLength - 2]=(byte)((b1 << 2) | (b2 >> 4));
			bytes[resultLength - 1]=(byte)((b2 << 4) | (b3 >> 2));
		}else{
			b1 = DECODE_TABLE [b[len - 4]];
			b2 = DECODE_TABLE [b[len - 3]];
			b3 = DECODE_TABLE [b[len - 2]];
			b4 = DECODE_TABLE [b[len - 1]];
			bytes[resultLength - 3] = (byte)((b1 << 2) | (b2 >> 4));
			bytes[resultLength - 2] = (byte)((b2 << 4) | (b3 >> 2));
			bytes[resultLength - 1] = (byte)((b3 << 6) | b4);
		}
		return new String(bytes,"UTF-8");
	}
	

	
	
	private static int getDecodeLength(byte[] b){
		int len=b.length;
		if(b[len-2] == DEFAULTF_PAD){//two '=',means modulus=1
			return (len / ENCODE_BLOCK) * UNENCODE_BLOCK - 2;
		}else if(b[len-1] == '='){
			return (len / ENCODE_BLOCK) * UNENCODE_BLOCK - 1;
		}else{
			return (len / ENCODE_BLOCK) * UNENCODE_BLOCK;
		}
	}
	
	private static int getEncodeLength(byte[] b){
		int len=b.length;
		if(len==0) return 0;
		return (((len+UNENCODE_BLOCK)-1)/UNENCODE_BLOCK)*ENCODE_BLOCK;
	}

	public static String base642Str(String str) throws UnsupportedEncodingException{
		return new String(Base64.decodeBase64(str.getBytes("UTF-8")),"UTF-8");
	}
	public static void main(String str[]) throws UnsupportedEncodingException{
		String testStr="测试base64位";
		String encodeStr=Base64Util.encode(testStr);
		System.out.println(encodeStr);
		String decodeStr=Base64Util.decode(encodeStr);
		System.out.println(decodeStr);
	}
	
}


分享到:
评论

相关推荐

    九宫重排c++实现

    用c++实现的九宫重排问题 能在vc++6.0下运行 适合于初学c++语言的同学 形象的展示了九宫重排问题

    matlab实现JPEG编码实践_jpeg 解码_matlab

    在本实践报告中,我们将深入探讨JPEG(Joint Photographic Experts Group)编码的理论与实践,以及如何使用MATLAB这一强大的编程环境进行JPEG编码和解码的实现。JPEG是一种广泛使用的有损图像压缩标准,尤其适用于...

    Algorithm-重排链表

    offer 重排链表 重排链表 重排链表 重排链表 重排链表

    python实现重排链表.md

    本文主要介绍了一种算法——如何使用Python语言实现链表的重排。所谓“重排链表”,是指将链表进行重新排列,使得链表的第一个节点与最后一个节点相邻,第二个节点与倒数第二个节点相邻,以此类推。这种重排方法在...

    车厢重排问题 C++实现

    《车厢重排问题的C++实现》 在IT领域,数据结构和算法是核心技能之一。本篇文章将探讨一个有趣的问题——车厢重排,以及如何使用C++来解决这个问题。这是一个涉及栈和队列的经典问题,它对于理解这两种数据结构的...

    基于FPGA的TCP段乱序重排设计与实现.pdf

    本文介绍了一种基于FPGA的TCP段乱序重排的设计与实现方法,旨在解决网络数据包由于网络拥塞等原因造成的乱序问题,从而保证数据传输的效率和质量。 TCP协议在数据传输过程中,会因为网络拥塞、传输错误或路由问题,...

    在链表操作中,"重排链表" 是一个常见的问题,其目标是将链表中的节点重新排列成这样的顺序:链表的前半部分包含原始链表中的前 n/

    重排链表在链表操作中,"重排链表" 是一个常见的问题,其目标是将链表中的节点重新排列成这样的顺序:链表的前半部分包含原始链表中的前 n/2 个节点(其中 n 是链表中的节点总数),链表的后半部分包含剩下的 n/2 个...

    JPEG图像压缩编码及解码源代码(可定图像品质级别)

    JPEG(Joint Photographic Experts Group)是一种广泛应用于数字图像处理中的有损压缩标准,它通过将图像数据转换为频域表示并应用量化和熵编码来实现高效的数据压缩。在这个"JPEG图像压缩编码及解码源代码(可定...

    重排九宫(广度优先)

    重排九宫的广度优先算法 有代价函数实现局部优先 用哈希表来看是否已经在open表中

    faad2解码aac

    **标题与描述解析** 标题"faad2解码aac"涉及到的是使用faad2库对AAC(Advanced ...以上就是关于"faad2解码aac"这一主题的详细知识点,涵盖了AAC编码、faad2解码器、Android NDK的使用,以及测试和音频处理的相关内容。

    重排链表.md

    重排链表.md

    火车车厢重排 使用栈最少

    在提供的C++程序中,使用了`vector&lt;stack&lt;int&gt;&gt; stk`来表示k条缓冲铁轨,`stack&lt;int&gt; dest`作为目标栈,存储已经按照正确顺序排列的车厢,`vector&lt;int&gt; path`则记录了最优重排的步骤。`minS`变量用于记录最少使用的...

    基于DCT的JPEG图像压缩编码算法的MATLAB实现

    在MATLAB中,我们可以使用`dct2`函数进行二维DCT,`quantize`进行量化,自定义Zigzag重排函数,然后构建霍夫曼编码表并进行编码。最后,可以将编码结果写入到二进制文件中,形成JPEG格式的压缩图像。 7. **MATLAB...

    火车车厢重排问题,队列,c语言.doc

    为了解决这个问题,我们可以使用队列来存储这些车厢,并使用算法来实现车厢的重排。 在这个实验中,我们使用三个队列来存储车厢的信息:一个队列用来存储输入的车厢号,另两个队列用来存储缓存出队顺序与序号。并...

    九宫格重排

    标题中的“九宫格重排”指的是经典的数独游戏,这是一种基于九宫格(3x3的小方格)布局的逻辑解谜游戏。在数独游戏中,玩家需要填充一个9x9的网格,使得每一行、每一列以及每一个3x3的宫格内,数字1到9都恰好出现一...

    polar_极化码编码_极化码_极化码编码_polar_信道编码_

    描述中提到的“简单的极化码编码译码”可能指的是使用Python编程语言实现的基本极化码编码器和解码器。通常,编码过程包括以下步骤: 1. 输入信息比特序列。 2. 应用极化变换,将信息比特与极化码构造矩阵进行矩阵...

    基于fpga的tcp乱序重排算法实现,通过verilog实现适用于fpga的tcp乱序重排算法,并通过实际数据测试验证 代码里

    基于fpga的tcp乱序重排算法实现,通过verilog实现适用于fpga的tcp乱序重排算法,并通过实际数据测试验证。 代码里包含注释,可以明白每个模块的含义。 采用自创的乱序重排算法,易于在硬件中实现。 该算法和工程可...

    UICollectionViewCell长按重排

    本教程将深入讲解如何实现"UICollectionViewCell长按重排"的功能,包括“长按”手势识别和“跨cell重排”的逻辑处理。 首先,我们要在UICollectionViewCell中添加长按手势识别器(UILongPressGestureRecognizer)。...

    RS_Y_matlab重排_重排_时频重排_

    在MATLAB中,可以使用`spectrogram`、`cwt`等函数进行时频分析,而自定义的重排算法可能需要利用矩阵操作、循环结构和一些高级函数来实现。理解这段代码需要对MATLAB编程、傅里叶变换、信号处理原理有一定的掌握。...

Global site tag (gtag.js) - Google Analytics