Python struct.error:struct格式的错误字符

Python struct.error:struct格式的错误字符,python,struct,format,Python,Struct,Format,首先,我想知道python这句话的作用: struct.unpack("!%sH" % (len(data) / 2), data)) 其次,我必须使用python生成ICMP请求消息,问题是我已经得到了老师给我的一些代码来帮助我: def step4(code, server, port): s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp')) CHARMAP =

首先,我想知道python这句话的作用:

struct.unpack("!%sH" % (len(data) / 2), data))
其次,我必须使用python生成ICMP请求消息,问题是我已经得到了老师给我的一些代码来帮助我:

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
问题是理论上所有这些代码都是正确的,所以我只应该执行“create_packet”函数,我在这里包括:

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
每当我执行脚本时,总会出现以下错误:

Traceback (most recent call last):
    File "gymkhana.py", line 256, in <module>
        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
回溯(最近一次呼叫最后一次):
文件“gymkhana.py”,第256行,在
main()
文件“gymkhana.py”,第19行,主
步骤4(标识符、服务器、ginkana_端口)
文件“gymkhana.py”,第181行,第4步
数据包=创建数据包(整数(代码))
文件“gymkhana.py”,第211行,在create_数据包中
校验和=校验和(消息头+消息有效负载)
文件“gymkhana.py”,第248行,大写
retval=sum16(数据)#和
sum16中第246行的文件“gymkhana.py”
返回和(结构解包(!%sH)%(len(数据)/2,数据))
struct.error:struct格式的字符不正确

作为对第一个问题的回答,这一行

struct.unpack("!%sH" % (len(data) / 2), data)    # in Python 2
struct.unpack("!%sH" % (len(data) // 2), data)   # in Python 3
也就是说,取
数据中的n个字节(示例:4个字节),并将它们解释为n/2个无符号短整数(示例:2个整数),每个整数有2个字节。
开头是关于字节顺序的,表示大端<代码>%s
根据
len(data)/2
的值转换为一个或多个数字,因此在本例中,这与执行相同

struct.unpack("!2H", data)
结构格式中的
坏字符
异常是因为您显示的代码使用了
/
除法运算符。这在Python2中是有效的。但是在Python3中,它需要是
/
。这是因为
/
在Python2中表示整数除法,但在Python3中表示浮点除法。在Python 3中

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

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

这解释了你的
坏字符
错误。

这是错误之前的数据内容:b'\x08\x00\x00\x00\x00\x07\x00\x07\x00\x00\x01\x10\xc6',如果我这样做:
data=b'\x08\x00\x00\x00\x00\x00\x07\x00\x01\x10\xc6'
后面跟着:
struct.unpc(!%sH'(len data)/2),data:
(2048,0,7,7,1,4294)
。你的
unpack
格式字符串中是否有一个有趣的字符在你粘贴代码时消失了?我刚刚检查了它,这就是我得到的。有趣的是,我尝试了你写在这里的相同命令,但我仍然得到了相同的错误(现在正在抓紧救命稻草)如果在
struct
格式字符串中使用
而不是
,会发生什么情况?如果使用函数
sum16()
并将其放在一个完全不同的程序中,然后将其输入
data=b'\x08\x00\x00\x00\x00\x00\x00\x07\x00\x01\x10\xc6'
会得到错误
结构格式的坏字符
,但如果在解释器提示下键入相同的行,会得到一个整数元组吗?