当前位置:   article > 正文

Base64编码解码_base解码

base解码

一.Base64编码的基本原理

1.基本介绍:

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输。那么,Base64到底起到什么作用呢?

在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现乱码情况。与此类似,网络上传输的字符并不全是可打印的字符,比如二进制文件、图片等。Base64的出现就是为了解决此问题,它是基于64个可打印的字符来表示二进制的数据的一种方法。

电子邮件刚问世的时候,只能传输英文,但后来随着用户的增加,中文、日文等文字的用户也有需求,但这些字符并不能被服务器或网关有效处理,因此Base64就登场了。随之,Base64在URL、Cookie、网页传输少量二进制文件中也有相应的使用。

2.Base64编码基本原理

Base64的原理比较简单,我们使用Base64时都会先定义一个类似这样的数组:

[‘A’, ‘B’, ‘C’, … ‘a’, ‘b’, ‘c’, … ‘0’, ‘1’, … ‘+’, ‘/’]
上面就是Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符,这是标准的Base64协议规定。在日常使用中我们还会看到“=”或“==”号出现在Base64的编码结果中,“=”在此是作为填充字符出现,后面会讲到。

3.具体转换步骤

第一步,将待转换的字符串每三个字节分为一组,每个字节占8bit,那么共有24个二进制位。
第二步,将上面的24个二进制位每6个一组,共分为4组。
第三步,在每组前面添加两个0,每组由6个变为8个二进制位,总共32个二进制位,即四个字节。
第四步,根据Base64编码对照表(见下图)获得对应的值。
0 A  17 R   34 i   51 z

1 B  18 S   35 j   52 0

2 C  19 T   36 k   53 1

3 D  20 U   37 l   54 2

4 E  21 V   38 m   55 3

5 F  22 W   39 n   56 4

6 G  23 X   40 o   57 5

7 H  24 Y   41 p   58 6

8 I  25 Z   42 q   59 7

9 J  26 a   43 r   60 8

10 K  27 b   44 s   61 9

11 L  28 c   45 t   62 +

12 M  29 d   46 u   63 /

13 N  30 e   47 v

14 O  31 f   48 w

15 P  32 g   49 x

16 Q  33 h   50 y

从上面的步骤我们发现:

Base64字符表中的字符原本用6个bit就可以表示,现在前面添加2个0,变为8个bit,会造成一定的浪费。因此,Base64编码之后的文本,要比原文大约三分之一。
为什么使用3个字节一组呢?因为6和8的最小公倍数为24,三个字节正好24个二进制位,每6个bit位一组,恰好能够分为4组。

4.示例说明

以下图的表格为示例,我们具体分析一下整个过程。
在这里插入图片描述
第一步:“M”、“a”、"n"对应的ASCII码值分别为77,97,110,对应的二进制值是01001101、01100001、01101110。如图第二三行所示,由此组成一个24位的二进制字符串。
第二步:如图红色框,将24位每6位二进制位一组分成四组。
第三步:在上面每一组前面补两个0,扩展成32个二进制位,此时变为四个字节:00010011、00010110、00000101、00101110。分别对应的值(Base64编码索引)为:19、22、5、46。
第四步:用上面的值在Base64编码表中进行查找,分别对应:T、W、F、u。因此“Man”Base64编码之后就变为:TWFu。

5.位数不足情况

上面是按照三个字节来举例说明的,如果字节数不足三个,那么该如何处理?
在这里插入图片描述
两个字节:两个字节共16个二进制位,依旧按照规则进行分组。此时总共16个二进制位,每6个一组,则第三组缺少2位,用0补齐,得到三个Base64编码,第四组完全没有数据则用“=”补上。因此,上图中“BC”转换之后为“QKM=”;
一个字节:一个字节共8个二进制位,依旧按照规则进行分组。此时共8个二进制位,每6个一组,则第二组缺少4位,用0补齐,得到两个Base64编码,而后面两组没有对应数据,都用“=”补上。因此,上图中“A”转换之后为“QQ==”;

6.注意事项

大多数编码都是由字符串转化成二进制的过程,而Base64的编码则是从二进制转换为字符串。与常规恰恰相反,
Base64编码主要用在传输、存储、表示二进制领域,不能算得上加密,只是无法直接看到明文。也可以通过打乱Base64编码来进行加密。
中文有多种编码(比如:utf-8、gb2312、gbk等),不同编码对应Base64编码结果都不一样。

二.C程序源码

/***************************.h******************************/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <stdarg.h>
#define u8 unsigned char

#define u32 unsigned long

static void codeBase(char* basestr, char* str);//对字符串进行BASE64编码

static void decodeBase64(char* basestr, char* str);//对字符串进行    BASE64解码

/************************************************.c********************************************************/
#include "base64.h"

int main(void)
{
	char str[] ="123456789@qq.com";
	char basestr[40] = {0};         
	
	codeBase(basestr, str);         //对字符串进行BASE64编码
	printf("basestr= %s\n", basestr);

	decodeBase64(basestr, str);     //对字符串进行BASE64解码
	printf("str= %s\n", str);

	system("pause");
	return 0;
}
/**
 * 功能:对字符串进行BASE64编码
 * 参数:
 *      basestr:编码后存储缓冲指针
 *      str:待编码缓冲区指针
 * 返回值:None
 * 说明:
 *       对于传址处理的函数,一定要保证所传地址对应的
 *       空间足够大,才可以避免内存溢出。
 */
static void codeBase(char* basestr, char* str)
{
	/*BASE64编码表*/
	const char Base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

	unsigned char len = strlen(str);
	unsigned char remain = len % 3;
	unsigned char i, j = 0;

	/*清空残留*/
	//memset(basestr, 0, strlen(basestr));
	/*每3个字节为一组进行切分*/
	for (i = 0; i < len; i += 3)
	{
		/*不够3字节时进行补充*/
		if (len - i == remain)
		{
			/*剩一个字节(8bits)时,可以拆分成两个6bits的字节,
			 *第二个6bits字节低4bits不够用0填充
			 *剩两个字节时,可以拆分成3个6bits的字节,第三个6bits字节
			 *低4bits不够用0填充*/
			if (remain == 1)
			{
				basestr[j++] = Base64_table[str[i] >> 2];
				basestr[j++] = Base64_table[(str[i] & 0x03) << 4 | 0x00];
				basestr[j++] = '=';
				basestr[j] = '=';
			}
			else if (remain == 2)
			{
				basestr[j++] = Base64_table[str[i] >> 2];
				basestr[j++] = Base64_table[(str[i] & 0x03) << 4 | (str[i + 1] & 0xF0) >> 4];
				basestr[j++] = Base64_table[(str[i + 1] & 0x0F) << 2 | 0x00];
				basestr[j] = '=';
			}
			else
			{

			}
			break;
		}

		/*够3字节将3字节拆分成4个有效位数为6位的字节,并查表赋值*/
		basestr[j++] = Base64_table[str[i] >> 2];
		basestr[j++] = Base64_table[(str[i] & 0x03) << 4 | (str[i + 1] & 0xF0) >> 4];
		basestr[j++] = Base64_table[(str[i + 1] & 0x0F) << 2 | (str[i + 2] & 0xC0) >> 6];
		basestr[j++] = Base64_table[str[i + 2] & 0x3F];

	}
}
/**
 * 功能:对字符串进行BASE64解码
 * 参数:
 *      basestr:待解码存储缓冲指针
 *      str:存储解码结果缓冲区指针
 * 返回值:None
 */
static void decodeBase64(char* basestr, char* str)
{
	const char Base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	unsigned char len;
	unsigned char i, j = 0;
	unsigned char remain;

	if (strstr(basestr, "="))
	{
		len = strstr(basestr, "=") - basestr;
	}
	else
	{
		len = strlen(basestr);
	}

	remain = len % 4;

	for (i = 0; i < len; i += 4)
	{
		/*不足4个6bits字节时进行的处理*/
		if (len - i == remain)
		{
			if (remain == 2)
			{
				str[j++] = (strchr(Base64_table, basestr[i]) - Base64_table) << 2 | (strchr(Base64_table, basestr[i + 1]) - Base64_table) >> 4;
			}
			else if (remain == 3)
			{
				str[j++] = (strchr(Base64_table, basestr[i]) - Base64_table) << 2 | (strchr(Base64_table, basestr[i + 1]) - Base64_table) >> 4;
				str[j++] = (strchr(Base64_table, basestr[i + 1]) - Base64_table) << 4 | (strchr(Base64_table, basestr[i + 2]) - Base64_table) >> 2;
			}
			else
			{

			}
			break;
		}

		/*大于等于4个6bits字节时进行的处理*/
		str[j++] = (strchr(Base64_table, basestr[i]) - Base64_table) << 2 | (strchr(Base64_table, basestr[i + 1]) - Base64_table) >> 4;
		str[j++] = (strchr(Base64_table, basestr[i + 1]) - Base64_table) << 4 | (strchr(Base64_table, basestr[i + 2]) - Base64_table) >> 2;
		str[j++] = (strchr(Base64_table, basestr[i + 2]) - Base64_table) << 6 | (strchr(Base64_table, basestr[i + 3]) - Base64_table);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 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
  • 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
  • 62
  • 63
  • 64
  • 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
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 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
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号