在python中将整数转换为字节

时间:2019-07-30 23:38:43

标签: python arrays byte

我试图将多个整数参数更改为字节,然后将它们放入字节数组。我拥有大多数所需的答案,但是我的字节数组中的前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

1 个答案:

答案 0 :(得分:2)

您似乎正在构建一个IPv4数据包头(假设您知道这种情况,您应该在问题中提到这一点)。

您的逻辑当前采用version并将其作为整个字节(8位)附加到您的字节数组,但它仅应占据前4位(或1个半字节)

您可能期望第一个字节为“ E”,因为0b0100_0101(即,4 represented as 4 bits后跟5 represented as 4 bits,如下图所示)是十进制的69 ,这是“ E”的ASCII字符。因此,如果要在TCPv4数据包上运行stringshexdump,则可能会看到“ E”作为第一个字符。但是,第一个字节实际上应该是0x45,因此您会混淆初始字节的表示形式。

enter image description here

您的代码不太正确,因为当versionhdrlen应该与两个单独的半字节在同一个字节中时,它们会将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

这应该给您足够的指导。祝你好运。