`
GhostFromheaven
  • 浏览: 394013 次
  • 性别: 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
分享到:
评论

相关推荐

    binhex[GhostFromHeavn]

    binhex[GhostFromHeavn] Python 二进制文件与十六进制格式文本文件转换

    Python读取图片为16进制表示简单代码

    主要介绍了Python读取图片为16进制表示简单代码,具有一定借鉴价值,需要的朋友可以参考下

    txt2bin

    TXT2BIN 文本文件到二进制文件的转换器。 从写入文本文件的十六进制数字生成二进制文件。 可以使用#注释掉。 没有保修。 使用选项卡和#在右侧注释掉。 不支持空格。

    python cookbook(第3版)

    5.10 内存映射的二进制文件 5.11 文件路径名的操作 5.12 测试文件是否存在 5.13 获取文件夹中的文件列表 5.14 忽略文件名编码 5.15 打印不合法的文件名 5.16 增加或改变已打开文件的编码 5.17 将字节写入...

    易化的Python-易语言

    使用易语言 设计Python窗口组件 易友专属,毕竟易语言组件操作功能齐全也方便 ...2.191103 版本更新: 1.增加组件,组合框,超级列表框代码...组合数据_排列组合进制_十到二进制_十到八进制_十到十六进制_二到十进制_八到十

    tengge py for s60编程教程

    8.2文件的十六进制读取写入 8.3文件路径的分割 8.4模拟按键 8.5按键捕获 8.6%格式化输出 8.7取得时间日期 8.8其他技术介绍 8.9.后台信息提示 9.0.字体和模式字体 9.1.文本界面其他函数 9.2.焦点控制 9.3.设定程序...

    txt2hex

    文本到十六进制转换器以进行内存初始化该脚本用于将文本二进制格式转换为十六进制(每行都有地址值),以创建内存初始化文件。局限性排除的文件扩展名仅是“ .txt”格式。 最小字数限制为32 。 地址宽度必须为2的...

    athena_bot:雅典娜(Athena)机器人-一款适用于esolangs的小型实用IRC机器人!

    十进制,二进制,十六进制互转换器,语言翻译器和XKCD浏览器,以及Brainfuck文本生成器! 它只需要'pytz'库,可以使用以下命令(在Ubuntu / Debian上)获取该库: apt-get install python-tz 只需使用以下命令...

    正则表达式经典实例.pdf

    6.3 二进制数 6.4 删除前导 6.5 位于某个特定范围之内的整数 6.6 在某个特定范围之内的十六进制数 6.7 浮点数 6.8 含有千位分隔符的数 6.9 罗马数字 第7章 URL、路径和Internet地址 7.1 URL合法性验证 7.2 在全文中...

    正则表达式经典实例

    6.3 二进制数 6.4 删除前导 6.5 位于某个特定范围之内的整数 6.6 在某个特定范围之内的十六进制数 6.7 浮点数 6.8 含有千位分隔符的数 6.9 罗马数字 第7章 URL、路径和Internet地址 7.1 URL合法性验证 7.2 ...

    MySQL5.1参考手册官方简体中文版

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. mysqlshow-...

    MySQL 5.1中文手冊

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. mysqlshow-...

    MySQL 5.1参考手册 (中文版)

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. mysqlshow-...

    mysql官方中文参考手册

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. mysqlshow-...

    MYSQL中文手册

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. ...

    MySQL 5.1参考手册中文版

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. ...

    MySQL 5.1参考手册

    8.6. mysqlbinlog:用于处理二进制日志文件的实用工具 8.7. mysqlcheck:表维护和维修程序 8.8. mysqldump:数据库备份程序 8.9. mysqlhotcopy:数据库备份程序 8.10. mysqlimport:数据导入程序 8.11. mysqlshow-...

    南开大学《大学计算机基础》在线作业04.docx

    A:EBCDIC码 B:ASCII码 C:原码 D:BCD码 参考选项:B 二进制数1010011.110转换为十六进制数为( )。 A:53.6 B:53.C C:123.6 D:A3.C 南开大学《大学计算机基础》在线作业04全文共8页,当前为第3页。参考选项:B 南开...

Global site tag (gtag.js) - Google Analytics