我试图将多个整数参数更改为字节,然后将它们放入字节数组。我拥有大多数所需的答案,但是我的字节数组中的前2个字节与所需的答案不同。代码中的所有if语句都是整数格式的for错误,并且for循环根据整数的大小来决定要分配给参数的字节数。
我已经在Mac和Linux计算机上进行了尝试,但仍然得到相同的答案。
def composepacket (version, hdrlen, tosdscp, totallength, identification, flags, fragmentoffset, timetolive, protocoltype, headerchecksum, sourceaddress, destinationaddress):
if version != 4:
return 1
elif hdrlen < 0 or hdrlen > 15:
return 2
elif tosdscp < 0 or tosdscp > 63:
return 3
elif totallength < 0 or totallength > 65535:
return 4
elif identification < 0 or identification > 65535:
return 5
elif flags < 0 or flags > 7:
return 6
elif fragmentoffset < 0 or fragmentoffset > 8191:
return 7
elif timetolive < 0 or timetolive > 255:
return 8
elif protocoltype < 0 or protocoltype > 255:
return 9
elif headerchecksum < 0 or headerchecksum > 65535:
return 10
elif sourceaddress < 0 or sourceaddress > 4294967295:
return 11
elif destinationaddress < 0 or destinationaddress > 4294967295:
return 12
else:
list1 = [version,hdrlen,tosdscp,totallength,identification,flags,fragmentoffset,timetolive,protocoltype,headerchecksum,sourceaddress,destinationaddress]
final = bytearray()
for element in list1:
if element <= 255:
x = element.to_bytes(1,byteorder='big')
final += x
elif element <= 65535:
x = element.to_bytes(2,byteorder='big')
final += x
elif element <= 16777215:
x = element.to_bytes(3,byteorder='big')
final += x
elif element <= 4294967295:
x = element.to_bytes(4,byteorder='big')
final += x
return final
测试行是
print(composepacket(4,5,0,1500,24200,0,63,22,6,4711, 2190815565, 3232270145))
预期答案是
bytearray(b'E\x00\x05\xdc^\x88\x00?\x16\x06\x12g\x82\x951M\xc0\xa8\x87A')
我得到的答案是
bytearray(b'\x04\x05\x00\x05\xdc^\x88\x00?\x16\x06\x12g\x82\x951M\xc0\xa8\x87A')
所以区别是我得到b'\ x04 \ x05的前两个字节,我应该得到b'E
答案 0 :(得分:2)
您似乎正在构建一个IPv4数据包头(假设您知道这种情况,您应该在问题中提到这一点)。
您的逻辑当前采用version
并将其作为整个字节(8位)附加到您的字节数组,但它仅应占据前4位(或1个半字节)
您可能期望第一个字节为“ E”,因为0b0100_0101
(即,4 represented as 4 bits
后跟5 represented as 4 bits
,如下图所示)是十进制的69 ,这是“ E”的ASCII字符。因此,如果要在TCPv4数据包上运行strings
或hexdump
,则可能会看到“ E”作为第一个字符。但是,第一个字节实际上应该是0x45
,因此您会混淆初始字节的表示形式。
您的代码不太正确,因为当version
和hdrlen
应该与两个单独的半字节在同一个字节中时,它们会将first_byte = version << 4 | length
和# -*- coding: utf-8 -*-
from scrapy.exceptions import DropItem
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, Boolean, Sequence, Date, Text
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
import datetime
DeclarativeBase = declarative_base()
def db_connect():
"""
This function connections to the database. Tables will automatically be created if they do not exist.
See __tablename__ under RateMds class
MySQL example: engine = create_engine('mysql://scott:tiger@localhost/foo')
"""
return create_engine('sqlite:///reviews.sqlite', echo=True)
class GoogleReviewItem(DeclarativeBase):
__tablename__ = 'google_review_item'
pk = Column('pk', String, primary_key=True)
query = Column('query', String(500))
entity_name = Column('entity_name', String(500))
user = Column('user', String(500))
review_score = Column('review_score', Integer)
description = Column('description', String(5000))
top_words = Column('top_words', String(10000), nullable=True)
bigrams = Column('bigrams', String(10000), nullable=True)
trigrams = Column('trigrams', String(10000), nullable=True)
google_average = Column('google_average', Integer)
total_reviews = Column('total_reviews', Integer)
review_date = Column('review_date', DateTime)
created_on = Column('created_on', DateTime, default=datetime.datetime.now)
engine = db_connect()
Session = sessionmaker(bind=engine)
def create_individual_table(engine):
# checks for tables existance and creates them if they do not already exist
DeclarativeBase.metadata.create_all(engine)
create_individual_table(engine)
session = Session()
def get_row_by_pk(pk, model):
review = session.query(model).get(pk)
return review
class GooglePipeline(object):
def process_item(self, item, spider):
review = get_row_by_pk(item['pk'], GoogleReviewItem)
if review is None:
googlesite = GoogleReviewItem(
query=item['query'],
google_title=item['google_title'],
review_score=item['review_score'],
review_count=item['review_count'],
website=item['website'],
website_type=item['website_type'],
top_words=item['top_words'],
bigrams=item['bigrams'],
trigrams=item['trigrams'],
text=item['text'],
date=item['date']
)
session.add(googlesite)
session.commit()
return item
else:
raise DropItem()
[1]: https://docs.sqlalchemy.org/en/13/core/constraints.html
视为两个单独的字节。
所以,您想要类似的东西
after
这应该给您足够的指导。祝你好运。