`
GhostFromheaven
  • 浏览: 397067 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

【Python】二进制文件与Base64编码文本文件转换

阅读更多

前面的话

Python内置的base64模块,在这里http://docs.python.org/library/base64.html?highlight=base64#base64包括b64encodeb64decodeurlsafe_b64decode等,可以满足包括URL在内的文本编码需要。但是在用base64.encode编码二进制文件的时候,发现编码不完整,只有部分文件被编码了,base64.decode解码出来文件错误。可能是base64模块用来出来文本的?仔细分析发现,是忘记用二进制模式打开文件了。但是,自己实现base64模块基本功能也不是什么难事,不是要重复发明轮子,仅作为学习pythonbase64的练习。

用内置 base64模块转换二进制文件与base64编码文本文件方法如下:

import base64
fin = open(r"D:\2.zip", "rb")
fout = open(r"D:\2.x.txt", "w")
base64.encode(fin, fout)
fin.close()
fout.close()

fin = open(r"D:\2.x.txt", "r")
fout = open(r"D:\2.x.zip", "wb")
base64.decode(fin, fout)
fin.close()
fout.close()

 

Base64介绍

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIMEemailemail via MIME, XML中存储复杂数据。

转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit0补足。然后,每次取出6(因为)个bit,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。

如果最后剩下两个输入数据,在编码结果后加1“=”;如果最后剩下一个输入数据,编码结果后加2“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

Base64索引表:

 

Value

Char

 

Value

Char

 

Value

Char

 

Value

Char

0

A

16

Q

32

g

48

w

1

B

17

R

33

h

49

x

2

C

18

S

34

i

50

y

3

D

19

T

35

j

51

z

4

E

20

U

36

k

52

0

5

F

21

V

37

l

53

1

6

G

22

W

38

m

54

2

7

H

23

X

39

n

55

3

8

I

24

Y

40

o

56

4

9

J

25

Z

41

p

57

5

10

K

26

a

42

q

58

6

11

L

27

b

43

r

59

7

12

M

28

c

44

s

60

8

13

N

29

d

45

t

61

9

14

O

30

e

46

u

62

+

15

P

31

f

47

v

63

/

 

二进制转成Base64编码

按照算法描述:

1、讲输入数据按3个字节组成一组3*8=24位的整数;

2、然后将其按24/6=4位一组分为4组;

3、每组6位算出取值,在base64索引表中查看对应的字符,即可;

4、如果还有模3剩余的1个字节数据,则补2个字节的0,将转换成的4字符的最后2个替换成”==”

5、如果还有模3剩余的2个字节数据,则补1个字节的0,将转换成的4字符的最后1个替换成”=”

其中1-3步容易理解和编写,第45步的实现方法可能有很多种,但是考虑到可读性,而且每次转换之多执行其中一步,可以使用如下中的硬编码:

 

_CODE_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

def binbase64(data):
	"""
	Convert binary data to Base64 format string.
	"""
	base64str = ""

	for i in range(len(data)/3):
		datavalue = ((data[3*i] << 16) | (data[3*i+1] << 8) | data[3*i+2])
		for j in range(4):
			base64str += _CODE_CHAR[(datavalue >> 6*(3-j)) & 0x3F]
	
	dataremain = len(data) % 3
	if dataremain == 1:
		datavalue = data[-1] << 16;
		base64str += _CODE_CHAR[(datavalue >> 18) & 0x3F]
		base64str += _CODE_CHAR[(datavalue >> 12) & 0x3F]
		base64str += "=="
	elif dataremain == 2:
		datavalue = (data[-2] << 16) | (data[-1] << 8);
		base64str += _CODE_CHAR[(datavalue >> 18) & 0x3F]
		base64str += _CODE_CHAR[(datavalue >> 12) & 0x3F]
		base64str += _CODE_CHAR[(datavalue >> 6) & 0x3F]
		base64str += "="
	return base64str

  

 

 

Base64解码转成二进制

 

解码之前要对输入数据有效性进行必要的判断,如长度是否为4的整数倍,有没有非法字符等。解码步骤为:

1、取4个字符组成一组,判断每个字符在Base64索引表中的索引值;

2、将索引值转成6位二进制,并组4*6=24位的整数;

3、再将这个24位的整数分成24/8=3个字节;

4、如果末尾有2个"==",则只有1个有效字节

5、如果末尾有1个"=",在有2个有效字节

 

class Base64Error(Exception):
	"""
	Exception for Base64 error.
	"""
	pass

def base64bin(encodedstr):
	"""
	Convert Base64 format string to binary data.
	"""
	if len(encodedstr) % 4:
		raise Base64Error("The length of input 'base64str' MUST be multiple of 4.")
	
	rawbase64str = encodedstr.rstrip("=")

	if (len(rawbase64str) % 4) == 1:
		raise Base64Error("Too many '=' characters, MUST NOT be more than 2.")

	for x in rawbase64str:
		if x not in _CODE_CHAR:
			raise Base64Error("Unexpected character %s.", x)
	
	data=[]
	for i in range(len(rawbase64str)/4):
		datavalue = (_CODE_CHAR.find(rawbase64str[4*i]) << 18) \
					| (_CODE_CHAR.find(rawbase64str[4*i+1]) << 12) \
					| (_CODE_CHAR.find(rawbase64str[4*i+2]) << 6) \
					| (_CODE_CHAR.find(rawbase64str[4*i+3]))
		data.append((datavalue >> 16) & 0xFF)
		data.append((datavalue >> 8) & 0xFF)
		data.append((datavalue) & 0xFF)
	
	strremain = len(rawbase64str) % 4
	if strremain == 2:
		datavalue = (_CODE_CHAR.find(rawbase64str[-2]) << 18) \
			| (_CODE_CHAR.find(rawbase64str[-1]) << 12)
		data.append((datavalue >> 16) & 0xFF)
	elif strremain == 3:
		datavalue = (_CODE_CHAR.find(rawbase64str[-3]) << 18) \
			| (_CODE_CHAR.find(rawbase64str[-2]) << 12) \
			| (_CODE_CHAR.find(rawbase64str[-1]) << 6)
		data.append((datavalue >> 16) & 0xFF)
		data.append((datavalue >> 8) & 0xFF)

	return data

 

 

 

字符串转换

 

def strbase64(astr):
	"""
	Convert a string to Base64 format string.
	"""
	return binbase64(map(ord, astr))
def base64str(encodedstr):
	"""
	Convert Base64 format string to a string.
	"""
	return "".join(map(chr,base64bin(encodedstr)))

 

  

 

文件转换

文件转换要用到这里介绍的filehleper。另外,RFC 822规定,Base64文本没行76个字符,可存76/4*3=57个字节。所以我们每次读入57个字节处理。

 

def binfiletobase64(inp, out):
	"""
	Convert binary file to Base64 format text file.
	"""
	blocksize = 76 / 4 * 3
	def _binfiletobase64(fin, fout):
		while True:
			chunk = fin.read(blocksize)
			if chunk:
				fout.write(strbase64(chunk))
				fout.write("\n")
			else:
				break
	
	fileinoutpattern(inp, out, _binfiletobase64, inmode="rb", outmode="w")

def base64filetobin(inp, out):
	"""
	Convert Base64 format text file to binary file.
	"""
	def _base64filetobin(fin, fout):
		for line in fin:
			fout.write(base64str(line.rstrip()))
	
	fileinoutpattern(inp, out, _base64filetobin, inmode="r", outmode="wb")

 

 

 

 

测试代码

def test():
	"""
	Self testing.
	"""
	rawstr = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."
	encodedstr = binbase64(map(ord, rawstr))
	for x in range(0, len(encodedstr), 76):
		print encodedstr[x:x+76]
	
	encodedstr = strbase64(rawstr)
	for x in range(0, len(encodedstr), 76):
		print encodedstr[x:x+76]
	
	data = base64bin(encodedstr)
	decodedstr =  "".join(map(chr,data))
	print decodedstr
	assert decodedstr == rawstr
	
	decodedstr = base64str(encodedstr)
	print decodedstr
	assert decodedstr == rawstr

	#base64str(encodedstr[:-1]);#Not multiple of 4
	#base64str(encodedstr[:-3]+"==");#Too many '='
	#base64str(encodedstr[:-2]+"()");#Invaild characters '(' and ')'

	binfiletobase64(r"D:\2.zip", r"D:\2.txt")
	base64filetobin(r"D:\2.txt", r"D:\2.1.zip")
	print "OK"

  

 

 

源代码下载binbase64.zip

14
50
分享到:
评论

相关推荐

    Python-f2b对目录及其文件进行base64编码解码的脚本文件

    Base64是一种用于将二进制数据转换为ASCII字符的编码方法,常用于在网络上传输非ASCII字符,如图片或某些特殊格式的文件。 "NHibiki-f2b-fa3fa26"是这个脚本的特定版本,可能是一个Git仓库中的特定提交哈希值,表示...

    文件转换为Base64编码

    在文件转换为Base64编码的过程中,首先会读取文件的二进制内容,然后按照Base64的规则进行转换。这个过程包括分组、编码和填充三个步骤: 1. **分组**:每个8位字节的二进制数据被分为3个一组,如果文件长度不是3的...

    base64-编码解码工具-python实现源码

    Base64是一种用于将二进制数据转换为可打印ASCII字符的编码方法,常用于在电子邮件等文本环境中传输非ASCII字符。Python作为一种功能强大的编程语言,内置了对Base64编码和解码的支持,使得开发者可以轻松地处理这类...

    Python3.7.2中文文档-标准库-Python二进制数据服务

    Python 3.7.2 的中文文档包含了对官方标准库的详尽解释,特别是“Python二进制数据服务”这一部分,它涵盖了处理不同类型二进制数据的核心模块。这些模块对于进行系统级编程、网络通信、文件操作以及数据存储至关...

    Python实现base64编码的图片保存到本地功能示例

    Base64是一种将二进制数据转换为可打印字符的编码方式,它常用于在网络上传输图像等非文本数据。本示例主要讲解如何使用Python将Base64编码的图片解码并保存到本地。 首先,我们要了解Python中进行Base64编码和解码...

    图片与Base64互转

    这个过程是通过对二进制数据进行分块,然后根据Base64编码规则将每块数据转换为对应的字符。 3. **生成Base64字符串**:最后,所有的Base64字符组合成一个字符串,这就是我们所说的Base64编码的图片。 ### 二、...

    将图片进行Base64编码后传输

    Base64是一种编码方法,源自ASCII字符集,用于将任意二进制数据转换成可打印的ASCII字符。它将每3个字节(24位)的数据分成4个6位组,并为每个6位组分配一个ASCII字符,从而形成一个可读的字符串。因为64是2的6次方...

    将图片文件转换为Base64字符串文本.zip

    在IT领域,Base64是一种常见的数据编码方法,它能够将二进制数据转换成ASCII字符串,便于在网络上传输和存储。在这个特定的压缩包文件中,重点是使用VB6(Visual Basic 6)编程语言将图片文件转换为Base64字符串。...

    base64转码器.zip

    用户可以通过这个工具将文本或二进制文件转换为Base64格式,以便在网络上传输或存储,也可以将Base64编码的数据还原回原始形式。 Base64编码的基本原理是将每3个字节(24位)的二进制数据转化为4个6位的二进制数,...

    Python程序设计:base64解码.pptx

    总的来说,Python的`base64`模块为处理Base64编码提供了全面的支持,无论是在网络通信、数据存储还是其他需要转换二进制数据为文本格式的场景,都能发挥重要作用。在实际项目中,理解并熟练使用这些函数能够帮助我们...

    HTTP二进制

    1. **Base64编码**:这是一种将二进制数据转换为ASCII字符的方法,以便在不支持二进制数据的传输环境中安全地传输。Base64编码后的数据通常比原始二进制数据更大,因为它增加了额外的字符用于表示数据。在HTTP中,...

    批处理实现base64转换

    在本案例中,"批处理实现base64转换"指的是使用批处理文件来实现对文件或文本的Base64编码和解码功能。Base64是一种将任意二进制数据转化为ASCII字符串的编码方式,常用于在网络上传输二进制数据,因为HTTP协议只能...

    用Python 将图片编码为base64数据,并保存为json文件

    Base64是一种用于将任意二进制数据转换为可打印字符的编码方式。在图片处理中,它可以把图片的二进制数据转化为ASCII字符串,方便在网络传输中使用,因为HTTP协议只支持文本传输。Base64编码会将原始数据按照每3个...

    base64 编码解码

    Base64编码的主要目的是将不可见的二进制数据转换成可见的文本格式,以便在网络上传输,因为很多协议(如电子邮件的MIME)只允许ASCII字符通过。 Base64编码的原理是将每3个字节的数据(24位)分为4组,每组6位,...

    泉中流版base64编码和解码(支持汉字等编码(utf-8))

    Base64编码是一种将二进制数据转换为可打印字符的方法,主要用于在电子邮件系统和文本文件中传输非ASCII字符。这种编码方式将每3个字节的数据转化为4个6位的字符,使得原本不可见的二进制数据可以以可见的ASCII字符...

    获得图片Base64代码的程序Demo_base64_图片_

    在IT行业中,Base64是一种常见的数据编码方法,它用于将二进制数据转换为可打印的ASCII字符串,便于在网络上传输。在这个“获得图片Base64代码的程序Demo_base64_图片_”中,我们将探讨如何使用编程语言将图片文件...

    图片base64编码互换源码

    在IT行业中,Base64编码是一种常见的数据编码方式,它将任意二进制数据转换为可打印的ASCII字符串。在处理图片时,由于图片本质上是二进制数据,因此可以使用Base64编码来将其转化为文本形式,方便在网络上传输或者...

    python的base64和pillow库实现的编码解码程序源代码

    Base64是一种编码方法,可以将二进制数据转换为可打印的ASCII字符,以便在文本环境中传输和存储。Python的base64库提供了编码和解码函数。使用base64库进行编码的步骤如下:将需要编码的数据转换为bytes类型。调用b...

    base64编码解码python版.txt

    对于Base64编码的文本,首先将其分割成每四个字符一组,然后将每组字符转换为Base64索引值,索引值为6位的二进制数。这些6位二进制数被拼接起来形成原始数据的二进制表示。如果存在一个或两个'='字符,它们会被忽略...

Global site tag (gtag.js) - Google Analytics