質問

i would say that this code would provide the same output three times but it does not:

import crcmod

#create CRC16 calculator
crc16 = crcmod.predefined.mkCrcFun('crc-16')

#wait for user input
#hstr = raw_input("enter hex commands, space separated: ")
hstr = '81 12 C0 00 01 05'
hex_series = hstr.replace(' ', '\\x')
hex_series_caps = hstr.capitalize().replace(' ', '\\x') #why is there difference?

print hex(crc16(hex_series))  # gives 0xd795 incorrect! + how can there be a 9???
print hex(crc16(hex_series_caps))  # gives 0x37b4 incorrect!
print hex(crc16('\x81\x12\xC0\x00\x01\x05')) # gives 0x815b correct!

please explain!

役に立ちましたか?

解決

Let's open a Python prompt...

>>> hstr
'81 12 C0 00 01 05'
>>> hex_series
'81\\x12\\xC0\\x00\\x01\\x05'
>>> hex_series_caps
'81\\x12\\xc0\\x00\\x01\\x05'

As you can see, none of the strings are the strings you want. Replacing spaces with "\\x" just inserts a bunch of backslashes and x characters into your string, it does not do any escaping.

An escape sequence like '\x63' will become 'c', but only if you write it that way in the source code. Escape sequences do not happen after string manipulation, reading strings, or almost anything else. For example,

>>> '\x63'
'c'
>>> '\\' + 'x63'
'\\x63'

Try this instead:

import base64
data = base64.b16decode(hstr.replace(' ', ''))
print hex(crc16(data))

他のヒント

The problem gets revealed once you put it into python console and look at the data:

>>> good = '\x81\x12\xC0\x00\x01\x05'
>>> hstr = '81 12 C0 00 01 05'
>>> hex_series = hstr.replace(' ', '\\x')
>>> hex_series_caps = hstr.capitalize().replace(' ', '\\x')
>>> good
'\x81\x12\xc0\x00\x01\x05'
>>> hex_series
'81\\x12\\xC0\\x00\\x01\\x05'
>>> hex_series_caps
'81\\x12\\xc0\\x00\\x01\\x05'

The main problem is that you put literaly the \x sign into it, whereas in the first good string it is translated - \xbla has special meaning which gets translated when you enter the string, having slash followed by x in a string is just a slash followed by x. (the second problem is that even if this worked, since you substitute space, the first one would not be converted).

What python is saying with the \\ in \\xc0 in the bottom is "this is a normal slash".

What Joe has stated is correct - so I won't repeat it. To correctly convert your input string, you can use the following:

blah = ''.join(chr(int(c, 16)) for c in hstr.split())
# '\x81\x12\xc0\x00\x01\x05'

edit: although using base64.b16decode() as shown by Dietrich Epp is more elegant IMHO

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top