Порядок байтов целых чисел в Python
-
05-07-2019 - |
Вопрос
Я работаю над программой, в которой сохраняю некоторые данные в виде целого числа и обрабатываю их побитово.Например, я могу получить число 48, которое буду обрабатывать побитно.В общем, порядок целых чисел зависит от машинного представления целых чисел, но делает ли Python что-нибудь, чтобы гарантировать, что целые числа всегда будут иметь прямой порядок байтов?Или мне нужно проверить порядок байтов, как в C, а затем написать отдельный код для этих двух случаев?
Я спрашиваю, потому что мой код работает на машине Sun, и хотя та, на которой он сейчас работает, использует процессоры Intel, в будущем мне, возможно, придется переключиться на машину с процессорами Sun, которые, как я знаю, имеют обратный порядок байтов.
Решение
Python int
имеет тот же порядок байтов, что и процессор, на котором он работает.А struct
Модуль позволяет преобразовывать байтовые объекты в целые числа (и наоборот, а также некоторые другие типы данных) собственным способом, с прямым порядком байтов или с прямым порядком байтов, в зависимости от строка формата твой выбор:начать формат с @
или нет символа порядка байтов для использования собственного порядка байтов (и собственных размеров - все остальное использует стандартные размеры), '~' для нативного кода, '<' для обратного байта, '>' или '!' для прямого порядка байтов.
Это побайтно, а не побитно;не совсем уверен, что вы подразумеваете под побитовой обработкой в этом контексте, но я предполагаю, что это можно реализовать аналогичным образом.
Для быстрой «массовой» обработки в простых случаях учтите также множество модуль -- fromstring
и tostring
методы могут быстро работать с большим количеством байтов, а byteswap
метод может дать вам «другой» порядок байтов (от собственного к неродному или наоборот), опять же быстро и для большого количества элементов (весь массив).
Другие советы
Если вам нужно обработать данные «побитово», то bitstring
модуль может вам помочь.Он также может иметь дело с порядком байтов между платформами (по крайней мере, в последней сборке магистрали, которая будет выпущена в ближайшие несколько дней).
Тем struct
модуль — лучший стандартный метод решения проблемы порядка байтов между платформами.Например, это упаковывает и распаковывает целые числа 1, 2, 3 в два «коротких» и один «длинный» (2 и 4 байта на большинстве платформ), используя собственный порядок байтов:
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
Чтобы программно проверить порядок байтов платформы, вы можете использовать
>>> import sys
>>> sys.byteorder
который либо вернет "big"
или "little"
.
Проверить когда?
При выполнении побитовых операций тип int будет иметь ту же последовательность, что и введенные вами значения. Вам не нужно это проверять. Вам нужно заботиться об этом только при преобразовании в / из последовательностей байтов на обоих языках, afaik.
В Python для этого вы используете модуль struct, чаще всего это struct.pack () и struct.unpack (). Р>
Следующий фрагмент расскажет вам, является ли ваш системный стандарт по умолчанию прямым порядком байтов (в противном случае это будет порядок байтов с прямым порядком байтов)
import struct
little_endian = (struct.unpack('<I', struct.pack('=I', 1))[0] == 1)
Обратите внимание, однако, что это не повлияет на поведение побитовых операторов: 1 < < 1
равно 2
независимо от порядка по умолчанию вашей системы. р>