本文介绍了精心制作的十六进制字符串以字符串格式正确,格式错误,一旦传递给unhexlify()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

def craft_integration(xintegration_time):

 integration_time = xintegration_time
 integration_time_str = str(integration_time)
 integration_time_str = integration_time_str.encode('utf-8')
 integration_time_hex = integration_time_str.hex()

 return integration_time_hex

def send_set_integration(xtime):

 int_time_hex = decoder_crafter.craft_integration(xtime)

 set_hex = "c1c000000000000010001100000000000000000000000004"+int_time_hex+"1400000000000000000000000000000000000000c5c4c3c2"
 set_hex = str(set_hex)
 print(set_hex)
 set_hex = unhexlify(set_hex)

例如,输入为"1000".使用craft_integration()变为31303030.然后将其插入默认的十六进制字符串.

输出为:

c1c000000000000010001100000000000000000000000004314310300301400000000000000000000000000000000000000c5c4c3c2

使用unhexlify()时,输出为:

b'\ xc1 \ xc0 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x10 \ x00 \ x11 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x041000 \ x14 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ xc5 \ xc4 \ xc3 \ xc2'

\ x041000是\ x04和1000的结合,它是原始输入值,而不是转换后的值.

为什么会这样?

解决方案

实际上,您所期望的只是通过bytes.__repr__的默认实现将您想要的值呈现为一种形式,而您并没有想到这一点.对您想要的没有帮助.

从一个更基本的层次开始:在Python中,bytes类型内的任何元素(嗯,任何字节",即8位一组)通常都以原始数字表示形式存储在机器中的某个位置,例如二进制的.为了将它们打印"到控制台上以供人类使用,必须将其转换为可由控制台解释的形式,以便可以使用正确的字形来表示基础值.对于许多值,例如0(或二进制格式的00000000),Python将使用\x00来表示. \是开始转义序列的转义字符,其后的x表示转义序列后面必须是2个十六进制字符,并且将这两个字符与整个序列组合在一起将形成该单字符的表示形式.字节使用四个字符.同样,对于255,在二进制中将是11111111,并且与bytes类型相同的值将被编码为\xff.

现在有例外-如果给定值在 ASCII 范围内,如果它位于可打印字符的范围内,则表示形式将是相应的ASCII字符.因此,对于十六进制30(十进制48),将其呈现为bytes类型的一部分将显示0而不是\x30,因为0是对应的可打印字符. /p>

因此对于您的情况,在控制台中以b'\x041000'形式打印的bytes表示实际上不是很大的\x值,因为\x转义序列仅适用于正好两个后续字符-所有后续字符(即1000)实际上都是使用可打印字符表示的,否则这些字符将表示为\x31\x30\x30\x30.

对于那些不介意使用字节的十进制表示法的人来说,还有另一种方法可用-只需将bytes转换为bytearray然后转换为list.我们将以两个nul字节(b'\x00\x00')为例:

>>> list(bytearray(b'\x00\x00'))
[0, 0]

显然,这两个nul字节将对应于两个零值.现在,尝试使用渲染为b'\x041000'的令人困惑的b'\x04\x31\x30\x30\x30':

>>> list(bytearray(b'\x041000'))
[4, 49, 48, 48, 48]

我们可以注意到,实际上是在5个元素的列表中用相应的十进制数字表示的5个字节.

通常很容易将实际值与在计算机控制台上显示和可视化的内容混淆.不幸的是,我们使用的工具有时会加剧这种混乱,但是作为程序员,我们应该理解这一点,并为我们的工作用户寻求将其最小化的方法,因为此示例表明并非所有人都凭直觉认为bytes的某些表示可能是表示为可打印的ASCII.

def craft_integration(xintegration_time):

 integration_time = xintegration_time
 integration_time_str = str(integration_time)
 integration_time_str = integration_time_str.encode('utf-8')
 integration_time_hex = integration_time_str.hex()

 return integration_time_hex

def send_set_integration(xtime):

 int_time_hex = decoder_crafter.craft_integration(xtime)

 set_hex = "c1c000000000000010001100000000000000000000000004"+int_time_hex+"1400000000000000000000000000000000000000c5c4c3c2"
 set_hex = str(set_hex)
 print(set_hex)
 set_hex = unhexlify(set_hex)

For example, input is '1000'.That becomes 31303030 with craft_integration().It is then inserted into the default hex string.

Output is:

c1c000000000000010001100000000000000000000000004313030301400000000000000000000000000000000000000c5c4c3c2

When unhexlify() is used, output is:

b'\xc1\xc0\x00\x00\x00\x00\x00\x00\x10\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x041000\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xc4\xc3\xc2'

\x041000 is an conjunction of \x04 and 1000 which was the original input value, not the converted value.

Why would this happen?

解决方案

What you have in fact is simply your desired value being rendered into a form by the default implementation of bytes.__repr__ that you were not expecting to the point that it was unhelpful to what you want.

To start from a more basic level: in Python, any element (well, any "byte", i.e. a group of 8 bits) inside a bytes type are typically being stored as raw digital representation somewhere in a machine as binary. In order to "print" them out onto a console for human consumption it must be turned into a form that may be interpreted by the console such that the correct glyph may be used to represent the underlying value. For many values, such as 0 (or 00000000 in binary), Python would use \x00 to represent that. The \ is the escape character to start an escape sequence, the x that follows signifies that the escape sequence is to be followed by 2 hexadecimal characters, and combining those two characters with the whole sequence would form the representation of that single byte using four characters. Likewise for 255, in binary that would be 11111111, and this same value as part of a bytes type will be encoded as \xff.

Now there are exceptions - if a given value falls inside the ASCII range, and that it in the range of printable characters, the representation will instead be the corresponding ASCII character. So in the case of the hexadecimal 30 (decimal 48), rendering of that as part of a bytes type will show 0 instead of \x30, as 0 is the corresponding printable character.

So for your case, a bytes representation that was printed out in the console in the form of b'\x041000', is not in fact a big \x value, as the \x escape sequence is only applied to exactly two subsequent characters - all following characters (i.e. 1000) are in fact being represented using the printable characters that would otherwise be represented as \x31\x30\x30\x30.

There is another method available to those who don't mind working with the decimal representation of bytes - simply cast the bytes into a bytearray then into a list. We will take two nul bytes (b'\x00\x00') as an example:

>>> list(bytearray(b'\x00\x00'))
[0, 0]

Clearly those two nul bytes will correspond to two zero values. Now try using the confusing b'\x04\x31\x30\x30\x30' which got rendered into b'\x041000':

>>> list(bytearray(b'\x041000'))
[4, 49, 48, 48, 48]

We can note that it was in fact 5 bytes rendered with the corresponding decimal numbers in a list of 5 elements.

It is often easy to get confused with what the actual value is, vs. what is being shown and visualized on the computer console. Unfortunately the tools we use sometimes amplify that confusion, but as programmers we should understand this and seek ways to minimize this for users of our work, as this example shows that not everyone may have the intuition that certain representations of bytes may instead be represented as printable ASCII.

这篇关于精心制作的十六进制字符串以字符串格式正确,格式错误,一旦传递给unhexlify()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 11:39