在Python中将ASCII码列表转换为字符串(字节数组)

45

我有一个整数ASCII值列表,需要将其转换为字符串(二进制),以用作密码操作的密钥。(我正在使用Python重新实现Java加密代码)

这个方法可以工作(假设是8字节密钥):

key = struct.pack('BBBBBBBB', 17, 24, 121, 1, 12, 222, 34, 76)

然而,我希望键长和unpack()参数列表不是硬编码的。

如果有一个初始的整数列表,我应该如何正确实现它呢?

谢谢!


为什么需要一个“二进制”字符串? - relet
222 不是 ASCII 值。这是一个打字错误,还是你的字节实际上是来自某个基于 ASCII 的国家代码页的字符? - cubuspl42
6个回答

58

对于 Python 2.6 及以上版本,如果您处理的是字节,则 bytearray 是最明显的选择:

>>> str(bytearray([17, 24, 121, 1, 12, 222, 34, 76]))
'\x11\x18y\x01\x0c\xde"L'
对我而言,这比Alex Martelli的回答还要更直接 - 仍然不需要字符串操作或len调用,但现在甚至不需要导入任何东西!

3
对于那些想知道的人,Alex Martelli的答案似乎更快,至少在我的Python 2.7.7基准测试中是这样的。对于10000次运行,他的答案是12ms,而这个答案则是18ms;这些数字重复性很好。尽管这不是很大的收益,但在处理大量数据时有所帮助。话虽如此,对我来说,这个答案实际上更快,只需要8毫秒:https://dev59.com/OXRB5IYBdhLWcg3wgHWr#12073686 - leetNightshade
3
在Python 3.4.1 x86中,根据我的基准测试结果,这种方法是最快的。 - leetNightshade
`>>> str(bytearray([42])) "bytearray(b'*')"
import sys; sys.version '3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:05:16) [MSC v.1915 32 bit (Intel)]'`
- Cees Timmerman

51

对于涉及到同类型值的序列操作,我更喜欢使用array模块而不是struct模块:

>>> import array
>>> array.array('B', [17, 24, 121, 1, 12, 222, 34, 76]).tostring()
'\x11\x18y\x01\x0c\xde"L'

不需要 len 调用,不需要字符串操作等 —— 快速、简单、直接,为什么要选择其他方法?!


2
这在逻辑上对我来说是最有意义的。谢谢你的提示! - mikewaters
5
自 Python 3.2 起,方法 tostring() 已被弃用。请使用 tobytes() 方法代替,这是更清晰的名称并且可以完成相同的功能。 - TylerH

48

这是在重新讨论一个旧问题,但在Python 3中,您可以直接使用bytes

>>> bytes([17, 24, 121, 1, 12, 222, 34, 76])
b'\x11\x18y\x01\x0c\xde"L'

优秀、简洁、清晰! - Jonas Byström
这可能是Python3的“最正确”的答案。 - thom_nic
如何做相反的操作?(字节 -> 数组) - Tino
1
@Tino:你是指将字节转换为列表吗?你可以直接使用list()函数:list(b'spam') → [115, 112, 97, 109] - Pi Delport

11
struct.pack('B' * len(integers), *integers)

*sequence 表示“解包序列” - 或者更确切地说,“在调用 f(..., *args ,...) 时,让 args = sequence”。


有趣的是,我应该意识到可以在字符串上使用乘法,但我不知道“解包序列”的存在。谢谢! - mikewaters
好的解决方案,还可以使用'%dB'%len(integers)或者甚至是'{}B'.format(len(integers)) - Sergio Ivanuzzo

7
key = "".join( chr( val ) for val in myList )

1

使用map()函数的简短版本(适用于Python 2.7):

"".join(map(chr, myList))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接