【问题标题】:PYTHON 3+: How to add a byte into a string without decodePYTHON 3+:如何在不解码的情况下将字节添加到字符串中
【发布时间】:2021-06-13 12:17:25
【问题描述】:

我想将一些字节放入一个字符串中。

所以我有我的字符串,我想预先添加 2 个字节(给定数字的十六进制值)

    given_num = 231
    bytes_num = given_num.to_bytes(2,'big')

    my_str = "abc__\x01\x02\x03__abc"
    my_str = str(bytes_num) + my_str

    print(my_str)
    print(bytes(my_str,'utf-8'))

输出是

b'\x00\xe7'abc__☺☻♥__abc
b"b'\\x00\\xe7'abc__\x01\x02\x03__abc"

我也尝试过使用解码方法,但如果十六进制值不是 'utf-8' 发生错误,或者如果我使用“忽略”或“替换”进行错误处理,它会更改值。仅当字节为“utf-8”时才有效。 也使用 'latin1' 和 'iso' ,同样的事情。 例如:

    given_num = 231
    bytes_num = given_num.to_bytes(2,'big')

    my_str = "abc__\x01\x02\x03__abc"
    my_str = bytes_num.decode("utf-8") + my_str

错误: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe7 in position 1: unexpected end of data

也试过 chr()

    given_num = 231

    my_str = "abc__\x01\x02\x03__abc"
    my_str = chr(given_num) + my_str

输出再次不是首选:

çabc__☺☻♥__abc
b'\xc3\xa7abc__\x01\x02\x03__abc'

如您所见,前 2 个字节是 [0xc3][0xa7],我想看到

b'\x00\xe7abc__\x01\x02\x03__abc'

(给定数字的十六进制值,以字节为单位)

在 C 语言中,我会执行上述操作

printf("%c%c some string ",0,231)

但这不适用于python格式:

    my_str = "abc__\x01\x02\x03__abc"
    my_str = "%c" % (231) + my_str

同样的输出,231 被翻译为 2 个字节 [0xc3][0xa7] 而不是 231 十进制数的一个字节十六进制表示 [0xe7]

çabc__☺☻♥__abc
b'\xc3\xa7abc__\x01\x02\x03__abc'

【问题讨论】:

    标签: python python-3.x byte


    【解决方案1】:

    你可以试试这样的:

    def do_stuff(input_str: str, nb1: int, nb2: int):
        return hex(nb1) + hex(nb2) + input_str
    
    
    print(do_stuff("test", 0, 231))
    

    这将导致这个字符串:0x00xe7test

    如果您想使用 \x 而不是 0x 表示法,您可以使用 str.replace 或 regex 来根据需要更改结果字符串。

    【讨论】:

    • 我需要放置实际字节,而不仅仅是十六进制值。如果我这样做,那么实际结果将是“\\x00\\xe7.....”我不在乎字节是否可打印,并且在大多数情况下不是。我希望得到与 C 代码相同的结果: printf(" a string with one non-printable byte %c",231)
    • 这样更好吗? def do_stuff(input_str: str, nb1: int, nb2: int): return f"{nb1:x}{nb2:x}{input_str}" print(do_stuff("test", 0, 231)) 你也可以使用c 而不是 x 将字节打印为 char 而不是十六进制值
    • 这会放入'e7'字符串。这就像打印十六进制值231。我想放入值为'e7'('\xe7')的字节。这不会在我的字符串中打印“e7”,因为它不是 utf-8。例如,如果我有字节“\x35”并将其放在一个字符串中,则将打印值“5”,而不是“35”,因为 5 用字节 0x35 表示。但是 0xe7 没有可打印的字符因此发生错误
    • 您是否在格式化字符串中尝试使用 c 而不是 x 的最后一个函数? def do_stuff(input_str: str, nb1: int, nb2: int): return f"{nb1:x}{nb2:x}{input_str}" print(do_stuff("test", 0, 231)) 我找到你了也可以使用 latin1 作为编码将字符串转换为字节,例如: print(bytes(do_stuff("abc__\x01\x02\x03__abc", 0, 231), encoding="latin1")) 这将导致相同的结果您在回答中提供了。如果您的代码足以满足您的要求,您可以接受您的答案以告知主题已解决。
    【解决方案2】:

    我将“可打印”字符串转换为字节
    然后我将字符串作为字节数组处理

        given_num = 231
        bytes1 = b"abc__\x01\x02\x03__abc"
        bytes2 = bytes([0,given_num])
        bytes_res = bytes2 + bytes1
        print(bytes_res) 
    

    输出:

    b'\x00\xe7abc__\x01\x02\x03__abc'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      • 2018-06-14
      • 2011-05-16
      • 2013-03-02
      • 2016-05-11
      • 2015-05-28
      相关资源
      最近更新 更多