python不支持的数据类型char,Python struct.error:结构格式错误的char

first of all I would like to know what this python sentence does:

struct.unpack("!%sH" % (len(data) / 2), data))

And secondly, I have to make an ICMP request message using python, and the thing is that I already got some code the teacher gave me to help:

def step4(code, server, port):

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp'))

CHARMAP = nonprintable_to_dots()

packet = create_packet(int(code))

s.sendto(packet, (server, port))

while True:

msg = s.recv(1600)

if not msg:

break

ihl = (ord(msg[0]) & 0x0F) * 4

icmp = msg[ihl:]

hexdump(icmp, True)

if cksum(icmp[:]) != 0:

print("wrong ckecksum!!")

def nonprintable_to_dots():

return str.join('', [c if c in printable[:-5] else '.' for c in map(chr, range(256))])

def hexdump(frame, with_time=False):

def to_chr(bytes):

retval = bytes.translate(CHARMAP)

return retval[:8] + ' ' + retval[8:]

def to_hex(bytes):

retval = str.join(' ', ["%02X" % ord(x) for x in bytes])

return retval[:23] + ' ' + retval[23:]

if with_time:

print('--' + time.strftime("%H:%M:%s"))

for i in range(0, len(frame), 16):

line = frame[i:i + 16]

print('%04X %-49s |%-17s|' % (i, to_hex(line), to_chr(line)))

print

def cksum(data):

def sum16(data):

"sum all the the 16-bit words in data"

if len(data) % 2:

data += '\0'

return sum(struct.unpack("!%sH" % (len(data) / 2), data))

retval = sum16(data) # sum

retval = sum16(struct.pack('!L', retval)) # one's complement sum

retval = (retval & 0xFFFF) ^ 0xFFFF # one's complement

return retval

The thing is that theoretically all this code is right, so I only should do the "create_packet" function, which I include here:

def create_packet(code):

ICMP_REQUEST = 8

checksum = 0

identifier = 7

sequence_number = 7

message_header = struct.pack("!BBHHH", ICMP_REQUEST, 0, checksum, identifier, sequence_number)

message_payload = struct.pack("!I", code)

checksum = cksum(message_header + message_payload)

message_header = struct.pack("!BBHHH", ICMP_REQUEST, 0, checksum, identifier, sequence_number)

return message_header + message_payload

Whenever I execute the script, I always get this error:

Traceback (most recent call last):

File "gymkhana.py", line 256, in

main()

File "gymkhana.py", line 19, in main

step4(identifier, server, ginkana_port)

File "gymkhana.py", line 181, in step4

packet = create_packet(int(code))

File "gymkhana.py", line 211, in create_packet

checksum = cksum(message_header + message_payload)

File "gymkhana.py", line 248, in cksum

retval = sum16(data) # sum

File "gymkhana.py", line 246, in sum16

return sum(struct.unpack("!%sH" % (len(data) / 2), data))

struct.error: bad char in struct format

解决方案

As answer to your first question, this line

struct.unpack("!%sH" % (len(data) / 2), data) # in Python 2

struct.unpack("!%sH" % (len(data) // 2), data) # in Python 3

says, take the n bytes in data (example: 4 bytes) and interpret them as n/2 unsigned short integers (example: 2 integers) of 2 bytes each. The ! at the beginning is about byte order and means big-endian. %s gets translated to one or more digits depending on the value of len(data) / 2, so in the example, it is the same as doing

struct.unpack("!2H", data)

Your bad char in struct format exception is because the code you present uses the / division operator. That is valid in Python 2. But in Python 3 it needs to be //. That is because / means integer division in Python 2, but floating-point division in Python 3. So in Python 3,

"!%sH" % (len(data) / 2)

comes out as

struct.unpack("!2.0H", data)

which explains your bad char error.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值