Base64算法原理及实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Base64算法原理及实现相关的知识,希望对你有一定的参考价值。
参考技术ABase64算法最开始是被用于解决电子邮件数据传输问题。在早期,由于历史原因问题,电子邮件只允许使用ASCII字符,如果在邮件中出现了非ASCII字符,在通过某些网关进行数据转发的时候,网关会对这些非ASCII字符做出调整,例如,把ASCII码8位二进制码的最高位置为0。此时接收方在收到邮件时就会出现乱码。基于这个原因,产生了Base64算法。
Base64编码的思路说白了,就是把传输数据的每个字节映射成ASCII码表中的某些字符,这样在传输的过程中,就不会出现乱码的问题了。Base64算法定义了一个映射表,如下所示。
由上表可以看出,之所以称为Base64编码,实际上是把原数据映射成了ASCII码表中的64个字符。但是,64个字符最多能映射的位数是6bit。但是每个数据是8bit的,那怎么转换呢?Base64编码的基本思想: 将原数据每3个字节(24bit)分为一组,然后将这24bit数据按照每6bit一组,重新划分为4组,分组完成之后,再将每每6bit数据为单元进行映射。
Base64编码的基本流程如下:
例如,将字符串"ABC"进行Base64编码流程如下。
所以,字符串"ABC"经过Base64编码后的数据是"QUJD"。
从Base64编码的原理可以看到,Base64实际上就是把原来数据中的每3个字节一组进行Base64编码转换,编码之后变成4个Base64字符。但是如果原文数据长度不是3的整数倍的时候该怎么办呢?Base64算法规定,如果待加密数据不是3的整数倍,就在原文数据后面补0,直到长度凑够3的整数倍为止,然后再进行Base64编码转换。待编码转换完成之后,在结果末尾补充相同个数的"="。
例如,将字符串"ABCD"进行Base64编码流程如下。
所以,字符串"ABC"经过Base64编码后的字符串是"QUJDRA=="。
其实这里有个规律,当原文的数据长度除以3余数为0时,编码之后后面没有"=";当余数为1时,后面有两个"=",当余数是2时,后面有一个"=","="的个数也就是补充的字节数。
通过Base64的原理可以看到,Base64编码实际上是把原数据的3个字节映射成了4个字节,所以相比于原数据长度,编码后的长度会增加1/3。这也会降低传输效率。
Get方式和Post方式是Http请求常用的两种方式,某些情况下会要求使用Get方式来传递二进制数据。这时,可以先通过Base64编码来将二进制数据转换成字符串数据。由于符号"+"和符号"/"是不允许出现在Url中的,所以,产生了Url安全的Base64算法,所谓的Url安全的Base64算法,其实主要包含两个方面。
目前,在Java中,我们可以通过以下方式来是使用Base64算法。
在java8之前,JDK官方库中都没有内置Base64算法,其实Base64实现很简单,这个不知道为什么。但是Java8内置了Base64编码器和解码器。
在Java8中,Base64工具类提供了三种BASE64编解码器:
1.基本Base64编码
也就是完全按照标准Base64的映射规则来编解码,不添加任何行标。
2.Url Base64编码
JDK标准类库中的Url Base64编码是用"-"和"_"取代了"+"和"/"
3.MIME Base64编码
Java类库中还提供了一种格式更友好的Base64编码,这种编码输出每行不超过76字符,并且使用\'\\r\'并跟随\'\\n\'作为分割。
4.去除填充符的Base64
在Java标准类库中,还提供了一种方式来去除编码末尾的"=",就是在构建Encoder 对象后调用withoutPadding()方法,例如:
Commons Codec是Apache为Java开发者提供的一个开源软件类库,该类库中主要是一些常用的编码工具类包,例如DES、SHA1、MD5、Base64,URL等。在使用该类库之前需要首先在Eclipse中添加依赖。Commons Codec提供了以下Base64编码方式。
1.基本Base64编码
Commons Codec和Java标准类库提供给的Base64编码方式是一样的。
2.Url Base64编码
Url Base64编码和Java类库也是一样的,把"+"和"/"替换成了"-"和"_",有一个不同的地方是Commons Codec中的Url Base64默认去掉了后面的"=",相当于Java类库中调用了withouPadding方法,例如:
3.类MIME格式输出
Commons Codec中也提供了类似于Java类库中的MIME的格式化输出,在Commons Codec中有一个方法:
这里的isChunked置为true,就表示是按照MIME格式输出编码结果。
h
排序算法原理及实现
算法一:直接插入排序
算法实现原理:就是计算一个新元素是应该放在哪里?每次进来一个都会进行和原来顺序进行重新组合。
代码实现:Java
public int[] testInsertionSort(int[] data){
// this methord is very easy.
for(int i = 1;i < data.length;i++){
int temp = data[i];
int j =i;
while(j>0 && data[j-1]>temp){
data[j] = data[j-1];
j--;
}
data[j] = temp;
}
return data;
}
算法二:希尔排序
算法原理:就是使用不同的长度进行排序,这只是在直接插入排序的基础上做了一些改进。
代码实现:Java
public int[] testInsertionShell(int[] data){
int length = data.length;
for(int d = length/2;d > 0;d/=2){
for(int i = d; i < length;i++){
int temp = data[i];
int j = i;
while( j >= d && data[j-d] > temp){
data[j] = data[j-d];
j -= d;
}
data[j] = temp;
}
}
return data;
}
算法三:选择排序
算法原理:每进行一次排序,找出最小值放在开始位置,依次进行。
代码实现:Java
public int[] testSelectSort(int[] data){
int length = data.length;
for(int i = 0;i < length-1; i++){
int j = i;
for(int k = i+1;k<length;k++){
if(data[k]<data[j]){
j = k;
}
}
if(j != i){
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
return data;
}
算法四:改进的选择排序
算法实现原理:在一次的排序过程中找到最大值和最少值。
代码实现:Java
public int[] testModifiedSelectSort(int[] data){
int length = data.length;
for(int i = 0; i < length/2;i++){
int maxIndex = length-i-1;
int minIndex = i;
for(int k= i+1; k < length;k++ ){
if(data[k]<data[minIndex]){
minIndex = k;
}
}
if(minIndex !=i){
int temp = data[minIndex];
data[minIndex] = data[i];
data[i] = temp;
}
for(int m = length-i-2;m>i;m--){
if(data[m]>data[maxIndex]){
maxIndex = m;
}
}
if(maxIndex !=length-i-1){
int temp = data[maxIndex];
data[maxIndex] = data[length-1-i];
data[length-1-i] = temp;
}
}
return data;
}
算法五:冒泡排序
算法实现原理:每进行一次排序,就可以得到一个最大值。
代码实现:
public int[] testBubbleSort(int[] data){
int length = data.length;
for(int i = 0; i < length-1;i++){
for(int j = 0;j < length-i-1;j++){
if( data[j] > data[j+1]){
int temp = data[j+1];
data[j+1] = data[j];
data[j] = temp;
}
}
}
return data;
}
算法六:快速排序
算法原理:使用一分为二的排序方式。
代码实现:
public int[] testQuickSort(int[] data,int left,int right){
if(left < right){
int i = left;
int j = right;
int x = data[i];
while(i < j){
while( i<j && data[j] > x){
j--;
}
if(i < j){
data[i++] = data[j];
}
while (i < j && data[i] < x){
i++;
}
if(i < j){
data[j--] = data[i];
}
}
data[i] = x;
testQuickSort(data,left,i-1);
testQuickSort(data,i+1,right);
}
return data;
}
算法七:堆排序
算法原理:就是构建堆,不断的将排好序的根节点和叶子节点进行交换,进行不断的调整堆。
代码实现:
public void buildHeapSort(int[] data, int root, int length) {
int lChild = root * 2 + 1;
if (lChild < length) {
int largest = lChild;
int rChild = lChild + 1;
if (rChild < length) {
if (data[lChild] < data[rChild]) {
largest = rChild;
}
if (data[root] < data[largest]) {
int temp = data[largest];
data[largest] = data[root];
data[root] = temp;
buildHeapSort(data, largest, length);
}
}
}
}
public int[] heapSort(int[] data) {
int length = data.length;
for (int root = length / 2 - 1; root >= 0; root--) {
buildHeapSort(data, root, length);
}
for (int i = length - 1; i >= 2; i--) {
int temp = data[0];
data[0] = data[i];
data[i] = temp;
buildHeapSort(data, 0, --length);
}
return data;
}
以上是关于Base64算法原理及实现的主要内容,如果未能解决你的问题,请参考以下文章
密码学Base64 编码 ( Base64 简介 | Base64 编码原理 | 最后编码组字节不足时补位 ‘=‘ 符号 | Base64 编码实现参考 )