Как разбить байт на верхнюю и нижнюю половинки - PullRequest
0 голосов
/ 31 октября 2018

Я пишу программу на Python, в которой я обрабатываю побайтовый файл, и пытаюсь написать функцию, которая разбивает байт на верхнюю и нижнюю половины. Для уточнения, скажем, я хочу запустить эту функцию в байте с десятичным значением 18 и шестнадцатеричным значением 12. Я бы хотел, чтобы он был разбит на два байта со значениями 1 и 2.

Вот функция, которую я написал для этого:

# split byte into upper and lower halves 
def splitByte(b): 
   lowerMask = b'\x0F' 
   lowerHalf = bytes(b & lowerMask[0])[0] 
   upperMask = b'\xF0' 
   upperHalf = bytes(b & upperMask[0])[0] 
   upperHalf = upperHalf >> 4 
   return [upperHalf,lowerHalf]

Вот где я вызываю функцию:

info = stream.read(1)
result = splitByte(info[0])
print(result)

Однако, когда я запускаю файл только с указанным выше кодом и функцией, происходит следующее:

[0, 0]
[0, 0]
[0, 0]
[0, 0]
Traceback (most recent call last):
  File "./test.py", line 8, in <module>
result = splitByte(info[0])
  File "<home folder>/byteops.py", line 21, in splitByte
    lowerHalf = bytes(b & lowerMask[0])[0]
IndexError: index out of range

Функция не только возвращает 0 для обоих значений, но и выдает ошибку на некоторых входах с ошибкой «индекс вне диапазона». Для контекста, вот файл, из которого я читаю, как показано в шестнадцатеричном редакторе:

00000000: 4C 49 54 35 30 0A 09 09 02 01

Я использую Manjaro Linux с Python 3.7.1. Как мне исправить мою функцию splitByte, или есть библиотечная функция, которая делает это для меня?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Ваша проблема в том, что преобразование из int в bytes. bytes(2) - запрос на байтовый массив из двух нулей. Вы можете просто использовать int манипуляции, которые вы уже знаете:

# split byte into upper and lower halves 
def splitByte(b): 
   lowerHalf = b & 15
   upperHalf = (b >> 4) & 15
   return [upperHalf,lowerHalf]

result = splitByte(18)
print(result)

Выход:

[1, 2]

Я оставил это как целые числа, поскольку вашей исходной программе требовалось только деление байтов, а не bytearray.

0 голосов
/ 31 октября 2018

Существует гораздо более простой способ сделать это. Вы можете использовать функцию ord для преобразования отдельного символа в его значение ASCII (в базе 10). Затем вы используете функцию hex для преобразования этого значения в шестнадцатеричное значение (в строке). Теперь вы можете легко получить доступ к верхней и нижней части вашего значения.

Вот пример:

val = 'a'
print(hex(ord(val))[2]) # 6
print(hex(ord(val))[3]) # 1

Вы получаете 6 и 1, поскольку шестнадцатеричное значение a равно 0x61.

Теперь, если вы напрямую получите десятичное значение каждого символа вашего исходного файла, вы можете избавиться от функции ord:

val = 97
print(hex(val)[2]) # 6
print(hex(val)[3]) # 1
...