`

Base64扩展,自定义字串和顺序

 
阅读更多

 

Base64很标准,sun 的 jdk 包含了实现,JS 也有许多可选实现。已知 sun 的 Base64 性能不行,远不及自己写的代码,这并不重要,无须深究。比较关注的是通常 JS 到 JAVA 间通常是私有的 Base64 编码和解码,如果采用公共的方式编码与解码,不能实现简单的加密。但可以通过适当的修改 Base64 来实现简单加密与解密。尽管不及专门的对称加密和非对称加密的安全性,但性能远胜于专门的加密解密过程,且可以实现可见字符的传输。适用于安全要求不高,对密文要求可见,且密文长度受限的场景。

 

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @author michael
 * 
 */
public class Base64x {
	private static final String DEFAULT_ENCODING_TABLES = "ABCDEFGHIJKLMNOPQRSTUVWXYZ+abcdefghijk0123456789/lmnopqrstuvwxyz";
	private String encodingTables = "";
	public Base64x(int offset) {
		int move = offset % DEFAULT_ENCODING_TABLES.length();
		this.encodingTables = DEFAULT_ENCODING_TABLES.substring(move) + DEFAULT_ENCODING_TABLES.substring(0, move);
	}

	/**
	 * encode
	 * 
	 * coverts a byte array to a string populated with base64 digits. It steps
	 * through the byte array calling a helper methode for each block of three
	 * input bytes
	 * 
	 * @param raw
	 *            The byte array to encode
	 * @return A string in base64 encoding
	 */
	public String encode(byte[] raw) {
		StringBuffer encoded = new StringBuffer();
		for (int i = 0; i < raw.length; i += 3) {
			encoded.append(encodeBlock(raw, i));
		}
		return encoded.toString();
	}

	/**
	 * encodeBlock
	 * 
	 * creates 4 base64 digits from three bytes of input data. we use an
	 * integer, block, to hold the 24 bits of input data.
	 * 
	 * @return An array of 4 characters
	 */
	protected char[] encodeBlock(byte[] raw, int offset) {
		int block = 0;
		// how much space left in input byte array
		int slack = raw.length - offset - 1;
		// if there are fewer than 3 bytes in this block, calculate end
		int end = (slack >= 2) ? 2 : slack;
		// convert signed quantities into unsigned
		for (int i = 0; i <= end; i++) {
			byte b = raw[offset + i];
			int neuter = (b < 0) ? b + 256 : b;
			block += neuter << (8 * (2 - i));
		}
		// extract the base64 digets, which are six bit quantities.
		char[] base64 = new char[4];
		for (int i = 0; i < 4; i++) {
			int sixbit = (block >>> (6 * (3 - i))) & 0x3f;
			base64[i] = getChar(sixbit);
		}
		// pad return block if needed
		if (slack < 1)
			base64[2] = '=';
		if (slack < 2)
			base64[3] = '=';
		// always returns an array of 4 characters
		return base64;
	}

	/**
	 * decode
	 * 
	 * convert a base64 string into an array of bytes.
	 * 
	 * @param base64
	 *            A String of base64 digits to decode.
	 * @return A byte array containing the decoded value of the base64 input
	 *         string
	 */
	public byte[] decode(String base64) {
		// how many padding digits?
		int pad = 0;
		for (int i = base64.length() - 1; base64.charAt(i) == '='; i--)
			pad++;
		// we know know the lenght of the target byte array.
		int length = base64.length() * 6 / 8 - pad;
		byte[] raw = new byte[length];
		int rawIndex = 0;
		// loop through the base64 value. A correctly formed
		// base64 string always has a multiple of 4 characters.
		for (int i = 0; i < base64.length(); i += 4) {
			int block = (getValue(base64.charAt(i)) << 18) + (getValue(base64.charAt(i + 1)) << 12) + (getValue(base64.charAt(i + 2)) << 6)
					+ (getValue(base64.charAt(i + 3)));
			// based on the block, the byte array is filled with the
			// appropriate 8 bit values
			for (int j = 0; j < 3 && rawIndex + j < raw.length; j++)
				raw[rawIndex + j] = (byte) ((block >> (8 * (2 - j))) & 0xff);
			rawIndex += 3;
		}
		return raw;
	}

	/**
	 * getChar
	 * 
	 * encapsulates the translation from six bit quantity to base64 digit
	 */
	protected char getChar(int sixBit) {
		return encodingTables.charAt(sixBit);
	}

	/**
	 * getValue
	 * 
	 * translates from base64 digits to their 6 bit value
	 */
	protected int getValue(char c) {
		if (c == '=')
			return 0;
		return encodingTables.indexOf(c);
	}

	public static void main(String[] args) {
		String data = "试一试中文也行。";
		Base64x b = new Base64x(0);
		String result = b.encode(data.getBytes());
		System.out.println(data);
		System.out.println(new String(result));
		System.out.println(new String(b.decode(result)));
	}
	
}
 
分享到:
评论

相关推荐

    自定义base64

    自定义的base64去掉=,等特殊应用字串

    C# Base64编解码

    在C#中,我们可以使用`System.Text.Encoding`命名空间下的`Convert`类和`Convert.ToBase64String()`方法来对字串进行Base64编码。例如,如果有一个字节数组`byte[] data`,可以这样编码: ```csharp string base...

    一个VB写的Base64编码/解码程序核心模块VB6源码

    '一个VB写的Base64编码/解码程序的核心编码解码模块VB源码 '本模块包含文件编码解码和纯字符串编码解码函数,需要进行二进制数据编码的请参考文件编码函数。 '因纯字串编码解码时用到 GetTempFileName 获取系统临时...

    Base64Encoder

    Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个Binary资料和字串资料彼此之间是可以互相转换的,十分方便。在实际应用上,Base64除了能将Binary资料可视化之外,也常用来表示字串加密过后的内容...

    Autohotkey之热字串和自动扩展

    Autohotkey 之热字串和自动扩展 Autohotkey 的热字串和自动扩展功能是其中非常重要的两个概念。热字串是指在 Autohotkey 中定义的一种特殊的热键,它可以实现自动扩展的功能。例如,当用户键入一些单词的缩写时,热...

    详解Java如何进行Base64的编码(Encode)与解码(Decode)

    它将任何二进制数据拆分成6位一组,然后映射到64个不同的字符中,这64个字符包括大小写字母、数字以及"+"和"/",并且通常在每76个字符后加上一个换行符,但非标准的Base64实现可能会有所不同。 在Java中,Base64...

    c语言实现aes ecb模式加密,可以和java,c#,obj-c互相 加,解密。包含base64编码,urlEncode编码

    c语言实现aes ecb模式加密,可以和java,c#,obj-c互相 加,解密。包含base64编码,urlEncode编码 注意,该算法里面的密文是转换成16进制的字串,如果不要16进制,可自行转换,内的函数。 vc6,vs2008,可编译。

    遍历电脑,找出含有相关字串的所有文件

    在IT领域,尤其是在软件开发和数据管理中,有时我们需要快速定位到包含特定字串的文件。这个任务可以通过编写脚本或者使用专门的搜索工具来实现。以下是一些关于如何遍历电脑并找出含有相关字串的所有文件的知识点:...

    c#读取自定义配置文件

    我们会遇到很多的配置参数:网站名称,上传图片后缀,上传文件后缀,关键字过滤,数据库连接字串等等,这些内容如果比较少的话,直接配置到Web.config文件中,借由.NET提供的操作类,将会非常方便的来操作这些自定义配置节点...

    字串替换器 1.05 版

    "字串替换器 1.05 版"是一款实用工具,主要用于文本处理中的字符串查找与替换操作。在日常的编程、文档编辑或数据分析中,我们经常需要批量修改大量文本中的特定字符或短语,这款软件就是为了满足这种需求而设计的。...

    html转C语言字串或数组工具

    4. **图片转换**:描述中提到的“还可以转图片”,意味着工具可能具备将HTML中的图片数据(如Base64编码)转换为C语言可以使用的格式,比如二进制数组。 5. **库依赖**:压缩包中的MFC42D.DLL、MFCO42D.DLL和MSVCRTD...

    android字串导出工具

    导出android代码内的字串到excel,便于翻译。 导出后的格式是: key 英文 待翻译的语言 导出时,会自动忽略不必要的字串。比如注释里带not translate,或者属性里有translate="false"的字串。 ------------ ./string...

    用v串替换s串中与t串相同的字串(定长顺序法)

    用v串替换s串中与t串相同的字串(定长顺序法)

    点睛字串替换器 1.05 版

    本程序是一个字串替换工具,主要对 VB、C、Delphi 编译的可执行文件中的 ASCII 及 UniCode 和文本格式的语言包文件进行字串替换的工作,作为对使用 VC、eXeScope、ResHaker 汉化的程序进行进一步的修饰之用。...

    2050:例5.20字串包含.cpp

    2050:【例5.20】字串包含 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 19468 通过数: 8142 【题目描述】 字符串移位包含问题。 对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾...

    Python-biglistofnaughtystrings淘气字串大列表收集了用户输入时经常出错的字串包含py脚本和JSON格式数据

    《Python淘气字串大列表:理解和应对用户输入异常》 在编程中,尤其是在与用户交互的场景下,处理用户输入是一项重要的任务。用户输入的数据可能会包含各种异常情况,如特殊字符、非法语法、编码问题等,这些异常...

    计算任意个字串之最大和 (求一个最大子串和的加强版)

    这个问题是求最大子串和问题的一个扩展,它不仅要求找到一个连续子数组的最大和,而是要求在所有可能的子数组组合中找到最大的和。在给定的代码中,使用了动态规划的方法来解决这个问题。 动态规划是一种有效解决...

    android字串的拆分问题

    本文将深入探讨“android字串的拆分问题”,并提供相关的解决方案。 字符串拆分是处理文本数据时的一项基本操作。在Java和Android中,我们可以使用多种方法来拆分字符串。主要的方法有两种:`split()` 和 `Pattern....

    一个简单的Des字串加密源代码

    1. **初始置换**:将64位的输入数据块进行初始置换,改变数据排列顺序。 2. **16轮迭代**:每轮都包含子密钥生成、数据替换和行移位三个步骤。子密钥生成是通过固定的PC-1和PC-2置换表以及循环左移操作得到16个48位...

Global site tag (gtag.js) - Google Analytics