简体   繁体   English

如何将java byte []转换为python字符串?

[英]How to convert java byte[] to python string?

I know that java and python handle bytes differently so I am a little bit confused about how to convert byte[] to python string I have this byte[] in java 我知道java和python处理字节的方式不同,所以我对如何将byte []转换为python字符串感到有些困惑,我在Java中有这个byte []

{ 118, -86, -46, -63, 100, -69, -30, -102, -82, -44, -40, 92, 0, 98, 36, -94 }

I want to convert it to python string here is how i did it 我想将其转换为python字符串,这是我的方法

b=[118, -86, -46, -63, 100, -69, -30, -102, -82, -44, -40, 92, 0, 98, 36, -94]
str=""
for i in b:
    str=str+chr(abs(i))

But I am not really sure if this is the correct way to do it. 但是我不确定这是否是正确的方法。

String concatenation is highly inefficient. 字符串连接是非常低效的。

I'd recommend to do that in a generator comprehension passed to str.join using an empty separator: 我建议使用空分隔符在传递给str.join的生成器理解中做到这一点:

s = "".join([chr(abs(x)) for x in b])

edit: the abs bit is weird. 编辑: abs位很奇怪。 It does what's requested, but nothing useful since byte is signed. 它可以执行请求的操作,但是由于byte已签名,因此没有任何用处。 So you'd need two's complement as in Martijn answer that fixes the next OP problem: data validity :) 因此,您需要像Martijn答案中那样的二进制补码,以解决下一个OP问题:数据有效性:)

It would be okay if you had some list of ASCII values in a table (and dropping abs allows us to use map , it's so rare to be able to use it let's not deprive us from doing so :) 如果您在表中有一些ASCII值列表是可以的(并且放下abs允许我们使用map ,但是很少能够使用它,所以我们不致于使它无法使用:)

items = [65, 66, 67, 68]
print("".join(map(chr,items)))

result: 结果:

"ABCD"

The Java byte type is a signed integer ; Java byte类型是有符号整数 the value ranges between -128 and 127. Python's chr expects a value between 0 and 255 instead. 值范围介于-128和127之间。Python的chr期望值介于0和255之间。 From the Primitive Data Types section of the Java tutorial: 在Java教程的“ 原始数据类型”部分中:

byte : The byte data type is an 8-bit signed two's complement integer. byte :字节数据类型是8位带符号的二进制补码整数。 It has a minimum value of -128 and a maximum value of 127 (inclusive). 最小值为-128,最大值为127(含)。

You need to convert from 2s compliment to an unsigned integer: 您需要将补码从2s转换为无符号整数:

def twoscomplement_to_unsigned(i):
    return i % 256

result = ''.join([chr(twoscomplement_to_unsigned(i)) for i in b])

However, if this is Python 3, you really want to use the bytes type: 但是,如果这是Python 3,则您确实要使用bytes类型:

result = bytes(map(twoscomplement_to_unsigned, b))

Assuming you're using Python 3, bytes can already be initialized from a list. 假设您使用的是Python 3,则可以从列表中初始化字节。 You'll need to convert the signed integers to unsigned bytes first. 您首先需要将有符号整数转换为无符号字节。

items = [118, -86, -46, -63, 100, -69, -30, -102, -82, -44, -40, 92, 0, 98, 36, -94]
data = bytes(b % 256 for b in items)
print(data)  # b'v\xaa\xd2\xc1d\xbb\xe2\x9a\xae\xd4\xd8\\\x00b$\xa2'

If the bytes represent text, decode it afterwards. 如果字节代表文本,请随后对其进行解码。 In your example, they do not represent text encoded to UTF-8, so this would fail. 在您的示例中,它们不代表编码为UTF-8的文本,因此将失败。

data = data.decode('utf8')
print(data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM