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

Python二进制文件与十六进制文本文件转换

阅读更多

 

Python有一个binhex模块,在http://docs.python.org/library/binhex.html,用来Encode and decode binhex4 files。我没搞懂binhex4格式,搜索了很久,找到一个讲的相对比较好的http://www.5dmail.net/html/2006-3-2/200632222823.htm

控制欲强的人,对未知或不可控充满恐惧。自己写个二进制与十六进制文件转换也许有点重复发明轮子的嫌疑,但是实现起来并没有想象的那么复杂,同时增加可控可用度,还有些意想不到的收获。

·filehelper

在《python判断对象是否为文件对象(file object)》中介绍了判断对象是否为文件对象(file object)的方法。这里就派上用场了。

还要介绍一个同时处理文件输入输出的帮助函数:

  1. def fileinoutpattern(inp, out, callback=None, inmode="r", outmode="wb"):
  2. """
  3. Make sure that 'inp' and 'out' has been 'converted' to file objects,
  4. and call 'callback' with them, finally clear it up.
  5. """
  6. # Set up
  7. fin = inp
  8. if not isfilelike_r(fin):
  9. fin = open(inp, inmode)
  10. fout = out
  11. if not isfilelike_w(fout):
  12. fout = open(out, outmode)
  13. # Call the 'callback'
  14. result = None
  15. if callback != None:
  16. result = callback(fin, fout)
  17. # Clear up
  18. if not isfilelike_r(inp):
  19. fin.close()
  20. if not isfilelike_w(out):
  21. fout.close()
  22. return result
def fileinoutpattern(inp, out, callback=None, inmode="r", outmode="wb"):
	"""
	Make sure that 'inp' and 'out' has been 'converted' to file objects, 
	and call 'callback' with them, finally clear it up. 
	"""
	# Set up
	fin = inp
	if not isfilelike_r(fin):
		fin = open(inp, inmode)
	fout = out
	if not isfilelike_w(fout):
		fout = open(out, outmode)
	
	# Call the 'callback'
	result = None
	if callback != None:
		result = callback(fin, fout)

	# Clear up
	if not isfilelike_r(inp):
	    fin.close()
	if not isfilelike_w(out):
	    fout.close()
	
	return result

 

1、判断inp是否为可读文件对象,如果不是就调用open,以inmode模式打开inp所指文件,并赋值给fin

2、判断out是否为可写文件对象,如果不是就调用open,以outmode模式打开out所指文件,并赋值给fou

3、如果callback不为None就调用它,并将返回结果保存在result

4、如果fin是我们自己打开的就关闭它;如果传进来的就是文件对象,则不关闭,避免重复关闭和非用户想要的关闭;

5、如果fout是我们自己打开的就关闭它;如果传进来的就是文件对象,则不关闭,避免重复关闭和非用户想要的关闭;

6、将callback的结果返回

这个很重要,却很简单。当然也可以写成类,像JunitTestCase那样的,写seuptearDown方法,分别在调用callback前后执行,这里这个函数就够了。

·binhex

回到我们的主题,有了这个帮助函数,怎么把二进制文件转成十六进制形式呢?

  1. def binhex(inp, out, extfun=lambda x: x, blocksize=256):
  2. """
  3. Convert a binary file 'inp' to binhex file output.
  4. The inp may be a filename or a file-like object supporting read() and close() methods.
  5. The output parameter can either be a filename or a file-like object supporting a write() and close() method.
  6. """
  7. def _binhex(fin, fout):
  8. filesize = 0
  9. while True:
  10. chunk = fin.read(blocksize)
  11. if chunk:
  12. redlen = len(chunk)
  13. for b in chunk:
  14. fout.write('%02X ' % extfun(ord(b)))
  15. fout.write('\n')
  16. filesize += redlen
  17. else:
  18. break
  19. return filesize
  20. return fileinoutpattern(inp, out, _binhex, inmode="rb", outmode="w")
def binhex(inp, out, extfun=lambda x: x, blocksize=256):
	"""
	Convert a binary file 'inp' to binhex file output.

	The inp may be a filename or a file-like object supporting read() and close() methods. 
	The output parameter can either be a filename or a file-like object supporting a write() and close() method.
	"""
	def _binhex(fin, fout):
		filesize = 0
		while True:
			chunk = fin.read(blocksize)
			if chunk:
				redlen = len(chunk)
				for b in chunk:				
					fout.write('%02X ' % extfun(ord(b)))
				fout.write('\n')
				filesize += redlen
			else:
				break
		return filesize
	return fileinoutpattern(inp, out, _binhex, inmode="rb", outmode="w")

 

1、需要inpout两个参数,指明输入和输出文件,一个应用在每个字节上的函数extfun,默认块大小为256字节;

2、定义一个嵌套的函数_binhex,实现处理逻辑:每次读入blocksize大小的数据,逐字节调用extfun处理,将处理的结果转成十六进制形式,并写入fout;每blocksize数据后添加换行;返回处理字节数;

3、调用fileinoutpattern传递对应的参数;

这里我们就可以发现,有了这个帮助函数,我们的函数变得非常简洁,逻辑也十分清晰。

·hexbin

binhex类似,将十六进制格式文本文件转成二进制文件也很简单:

  1. def hexbin(inp, out, extfun=slambda x: x):
  2. """
  3. Decode a binhex file inp to binary file outpu.
  4. The inp may be a filename or a file-like object supporting read() and close() methods.
  5. The output parameter can either be a filename or a file-like object supporting a write() and close() method.
  6. """
  7. def _hexbin(fin, fout):
  8. for line in fin:
  9. for i in range(len(line)/3):
  10. x = int(line[3*i:3*(i+1)], 16)
  11. fout.write(struct.pack('B', extfun(x)))
  12. fileinoutpattern(inp, out, _hexbin, inmode="r", outmode="wb")
def hexbin(inp, out, extfun=slambda x: x):
	"""
	Decode a binhex file inp to  binary file outpu.

	The inp may be a filename or a file-like object supporting read() and close() methods. 
	The output parameter can either be a filename or a file-like object supporting a write() and close() method.
	"""
	def _hexbin(fin, fout):
		for line in fin:
			for i in range(len(line)/3):
				x = int(line[3*i:3*(i+1)], 16)
				fout.write(struct.pack('B', extfun(x)))
	
	fileinoutpattern(inp, out, _hexbin, inmode="r", outmode="wb")

1、传人inpout作为输入和输出文件,一个应用在转换后每个字节上的函数extfun

2、定义一个嵌套函数_hexbin,实现处理逻辑:逐行读入,每3个字符一组,去掉空格,转成整数,在该整数上调用extfun,写入fout

3、调用fileinoutpattern传递对应的参数;

·测试代码

  1. def test():
  2. """
  3. Test case.
  4. """
  5. # binhex test
  6. zipfilename = r"D:\2.zip"
  7. binhex(zipfilename, r"D:\2.1.txt")
  8. with open(zipfilename, "rb") as fin:
  9. binhex(fin, r"D:\2.2.txt")
  10. with open(r"D:\2.3.txt", "w") as fout:
  11. binhex(zipfilename, fout)
  12. with open(zipfilename, "rb") as fin, open(r"D:\2.4.txt", "w") as fout:
  13. binhex(fin, fout)
  14. # hexbin test
  15. txtfile = r"D:\2.1.txt"
  16. hexbin(txtfile, r"D:\2.1.zip")
  17. with open(txtfile, "r") as fin:
  18. hexbin(fin, r"D:\2.2.zip")
  19. with open(r"D:\2.3.zip", "wb") as fout:
  20. hexbin(txtfile, fout)
  21. with open(txtfile, "r") as fin, open(r"D:\2.4.zip", "wb") as fout:
  22. hexbin(fin, fout)
  23. def XOR(x):
  24. def _XOR(y):
  25. return x ^ y
  26. return _XOR
  27. xor0x13 = XOR(0x13)
  28. binhex(zipfilename, r"D:\2.encode.txt", extfun=xor0x13)
  29. hexbin(r"D:\2.encode.txt", r"D:\2.5.zip", extfun=xor0x13)
  30. print "OK."
def test():
	"""
	Test case.
	"""
	# binhex test
	zipfilename = r"D:\2.zip"
	binhex(zipfilename, r"D:\2.1.txt")

	with open(zipfilename, "rb") as fin:
		binhex(fin, r"D:\2.2.txt")
	
	with open(r"D:\2.3.txt", "w") as fout:
		binhex(zipfilename, fout)

	with open(zipfilename, "rb") as fin, open(r"D:\2.4.txt", "w") as fout:
		binhex(fin, fout)
	
	# hexbin test
	txtfile = r"D:\2.1.txt"
	hexbin(txtfile, r"D:\2.1.zip")
	with open(txtfile, "r") as fin:
		hexbin(fin, r"D:\2.2.zip")
	
	with open(r"D:\2.3.zip", "wb") as fout:
		hexbin(txtfile, fout)

	with open(txtfile, "r") as fin, open(r"D:\2.4.zip", "wb") as fout:
		hexbin(fin, fout)

	def XOR(x):
		def _XOR(y):
			return x ^ y
		return _XOR
	xor0x13 = XOR(0x13)
	binhex(zipfilename, r"D:\2.encode.txt", extfun=xor0x13)
	hexbin(r"D:\2.encode.txt", r"D:\2.5.zip", extfun=xor0x13)

	print "OK."

 

1、这段测试代码用来测试功能是否正确实现已经足够了;

2、我们定义了XOR(x)的工厂方法,来生产异或函数对象,代码中我们生产了与0x13疑惑的函数对象xor0x13=XOR(0x13)

3、通过两次异或可以还原数据本身

·小结

AOP:面向切面编程,也许这个例子没有表现的那么明显。我们将“二进制/十六进制转换”与“文件()处理、文件关闭”等操作分开,作为该问题的两个不同切面。这样的好处就是,我们可以分开修改其中任意一个切面,而不影响或很少影响到另一个,换句话说给我们更大的灵活性和适应性,还有代码重用性。

嵌套函数:作为Python的一大特色,我们见到了它的用场。

工厂方法Factory Method:我们使用了XOR这个工厂方法来生产异或函数对象

 

 

源代码下载binhex.zip
0
12
分享到:
评论

相关推荐

    将二进制文件转换为16进制

    总结来说,将二进制文件转换为十六进制是计算机科学中的基本操作,它涉及文件I/O、数据类型转换以及可能的文本文件操作。了解这些知识对理解底层数据处理和软件开发至关重要。"VC 文件转换 bin 二进制 十六进制"这些...

    二进制 十进制 十六进制 编码转换 源码

    这段代码定义了四个函数,分别实现了二进制到十进制、十进制到二进制、十六进制到十进制以及十六进制到二进制的转换。你可以根据需要调用这些函数进行数值的转换。 在实际应用中,程序员可能会遇到各种编码转换问题...

    读入十六进制txt文件转十进制txt输出

    本话题主要涉及的是如何将一个包含十六进制数据的TXT文件读取并转换成十进制格式的TXT文件进行输出。这一过程需要理解二进制、十六进制和十进制之间的关系,以及如何在编程语言中进行这种转换。 首先,我们要了解...

    数值与十六进制文本的相互转换.rar

    以下将详细介绍数值与十六进制文本转换的相关知识点。 1. **数值系统**:计算机内部使用二进制(Base-2)来存储和处理信息。然而,人们通常使用十进制(Base-10)进行日常计算。此外,为了方便表示二进制数,十六...

    jpg图片转换成十六进制字符文件

    而“文件”则涵盖了输入的jpg文件和输出的十六进制文本文件。 至于压缩包子文件的文件名称列表中的“J2F”,这可能是由于上传过程中的命名错误或者是某种特定的文件格式,但在这个上下文中,它并不直接关联到jpg...

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

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

    16to10-2.rar_二进制数据_十六进制 转 十进制

    例如,在Python中,可以使用 `int(hex_number, 16)` 将十六进制转换为十进制,`bin(int(hex_number, 16))` 转换为二进制。了解这些基础转换对于学习和解决问题非常有帮助,尤其是在处理计算机数据和进行算法分析时。...

    mp3转换十六进制

    使用这样的工具,用户只需选择MP3文件,工具会自动完成转换并生成一个包含十六进制数据的文本文件。 在单片机端,十六进制文件可以被加载到闪存中,通过播放算法解码并逐字节地发送给音频DAC(数模转换器),从而...

    bin文件转换成十六进制数组

    "bin文件转换成十六进制数组"这个主题是关于将二进制数据转化为更适合编程和烧录的十六进制表示。这种转换对于嵌入式系统开发、固件更新、微控制器编程等工作尤为重要。 首先,我们要理解bin文件的性质。BIN是二...

    16进制转文件.zip

    2. **16进制转文件的原理**:将16进制字符串转换为文件,通常需要解析这些字符串,将每个16进制字符转换为其对应的二进制值,然后将这些二进制值组合成完整的字节序列。这个字节序列可以代表任何类型的数据,如文本...

    16进制 转换 bmp 转换16进制文本

    首先,你需要将16进制文本转换成字节,然后按照BMP文件的结构排列这些字节,包括创建正确的文件头和信息头。这个过程中需要特别注意位深度(通常是24位,即每个像素有红、绿、蓝三个通道,每个通道8位)和颜色模型...

    读取bmp文件的十六进制代码

    总结来说,读取BMP文件的十六进制代码涉及到理解BMP文件结构、使用编程语言的文件操作函数以及将二进制数据转换为可读的十六进制表示。这个过程可以帮助我们更好地理解和调试与图像相关的程序,同时对计算机视觉领域...

    二进制转换NEW.汉字转二进制 二进制转换汉字 汉字转二进制

    在计算机科学中,二进制是一种基础的数字系统,它仅使用两个符号:0 和 1,用于表示所有...总的来说,汉字转二进制涉及到字符编码理论、编码转换方法以及编程实践,这些都是理解和处理多语言文本时不可或缺的基础知识。

    大数16进制向10进制转换

    - 另一种优化是使用位运算,尤其是在二进制和十六进制之间转换时,可以利用位移操作提高效率。 6. **TestHexToDecimal** - 根据提供的压缩文件`TestHexToDecimal`,可能是包含一些测试用例或者代码示例,用于验证...

    十进制数向八进制、十六进制、二进制转换,

    在计算机科学中,数据通常以不同的进制系统表示,如十进制(Decimal)、八进制(Octal)、十六进制(Hexadecimal)和二进制(Binary)。这些进制系统各有特点,适应不同的计算需求。本文将详细介绍如何在这些进制...

    汉字转换成16进制,16进制转换成汉字

    在解析二进制文件时,通过16进制转换,我们可以更容易地分析和理解数据结构。 提到的"16进制汉字互转.exe"文件可能是一个实用工具,它提供了一个图形化的界面,让用户能够方便地进行汉字和16进制之间的转换。使用...

    ASCII码与十进制十六进制互相转化小工具

    在提供的压缩包文件"ASCII码与十进制十六进制互相转化例子"中,很可能包含了源代码或示例文件,用于演示如何实现这种转换功能。通过学习和研究这些代码,你可以了解如何在编程语言中实现这些转换操作,比如使用...

    奥贫血十六进制转换器

    标题中的“奥贫血十六进制转换器”可能是指一个专门用于进行二进制与十六进制之间转换的工具。在IT领域,进制转换是一项基本技能,尤其在处理计算机数据时,不同进制间的转换非常常见。二进制(Binary)是计算机内部...

    汉字中文十六进制显示转换

    例如,在Python中,可以使用内置的`binascii`模块的`hexlify`函数将字节转换为十六进制字符串,而`unhexlify`函数则可以反向操作。在C++中,可以使用`std::stringstream`和`std::hex`格式控制符进行转换。 至于...

    进制转换小程序

    进制转换是计算机科学中的基础概念,涉及到二进制(Binary)、八进制(Octal)、十进制(Decimal)和十六进制(Hexadecimal)等不同数字系统间的转换。这些进制转换在编程、数据存储、硬件设计等多个IT领域都有广泛...

Global site tag (gtag.js) - Google Analytics