Массив байтов в Python принимает только целые числа без знака

Я работаю над аудиокодеками в Python (yikes), используя байтовые массивы для редактирования отдельных байтовых данных из аудиофайла.

Я имею в виду определенное шифрование, которое требует от меня выполнения побитовых операций с отдельными байтами, хранящимися в массиве байтов.

Одной из таких операций является оператор ~ (побитовое НЕ), который по существу меняет бит (b'0001 становится b'1110).

Проблема в том, что когда вы ссылаетесь на один элемент массива байтов, он возвращает int (учитывает ли Python по умолчанию нетипизированные 8-битные целые числа данных?). Целые числа в Python по умолчанию подписаны (я не думаю, что целые числа без знака даже существуют в Python).

Когда вы пытаетесь выполнить побитовое НЕ для байта в массиве байтов, вы получаете следующую ошибку:

>>> array[0] = ~array[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: byte must be in range(0, 256)

Это потому, что он ожидает беззнаковое int в диапазоне от 0 до 255. Как мне преобразовать подписанный int в беззнаковый int, чтобы биты, используемые для представления обоих значений, остались прежними?

Ваше здоровье


person jmkmay    schedule 02.05.2018    source источник
comment
Я думаю, что numpy должен предоставлять беззнаковые целые числа. Я бы попробовал np.array (array) .astype (np.uint8)   -  person SpghttCd    schedule 03.05.2018
comment
Я имею в виду определенное шифрование - вы пишете свою собственную криптовалюту? Пожалуйста, не пишите собственную криптовалюту.   -  person user2357112 supports Monica    schedule 03.05.2018
comment
Ха-ха, нет ... Я бы никогда не попробовал ... пытаюсь подражать чему-то другому   -  person jmkmay    schedule 03.05.2018


Ответы (2)


Используйте другую операцию для переворота битов.

Например :1

array[i] = 255 - array[i]

или также:

array[i] = 255 ^ array[i]

перевернет все (т. е .: 8) бит.


1 математику, стоящую за этим, можно вычислить с помощью дополнения до двух страница википедии.

person fferri    schedule 02.05.2018
comment
Разве это не было бы 256 - array[0]? Оцените быстрый ответ. Такие вещи заставляют меня чувствовать себя глупо, хе-хе. - person jmkmay; 03.05.2018
comment
@JonathanMay: Нет. Если array[0] изначально 0, то 256 - array[0] равно 256, но желаемый результат - 255. - person user2357112 supports Monica; 03.05.2018
comment
@JonathanMay: почему бы тебе не попробовать и не посмотреть? for i in range(256): print('{:08b} {:08b}'.format(i, 255-i)) - person fferri; 03.05.2018
comment
@JonathanMay: на самом деле: all([{'0':'1','1':'0'}[c] for c in f'{i:08b}']==list('{:08b}'.format(255-i)) for i in range(256)) == True - person fferri; 03.05.2018
comment
@ user2357112 Но ~0 равно -1. Итак, 256 + ~0 это 255 - person jmkmay; 03.05.2018
comment
@JonathanMay: ~0 дает -1, но этот ответ не касается ~. - person user2357112 supports Monica; 03.05.2018

Решение на самом деле очень простое, если немного поиграться с двоичным калькулятором.

Просто вычтите величину SIGNED int из 256, чтобы получить значение UNSIGNED int с тем же двоичным представлением.

So,

-23 подписанный будет 233 беззнаковым.

Надеюсь, это поможет всем, кто ищет решение :)

РЕДАКТИРОВАТЬ: Для тех, кто говорит, ответ 255 - array[0]. В этом случае я ищу способ перейти от сообщения NOT'd int к его неподписанной части. Итак, я уже выполнил побитовое НЕ для целого числа, теперь я просто возвращаю его в форму, которую можно ввести в байтовый массив.

В итоге это будет выглядеть примерно так:

tmp = ~array[0]
array[0] = 256 + tmp

or

array[0] = 256 - abs(tmp)

Это дает мне правильный ответ :)

person jmkmay    schedule 02.05.2018
comment
Не 256. 255. Вычитание из 256 изменяет диапазон от 0-255 до 1-256. - person user2357112 supports Monica; 03.05.2018
comment
Или, если вы уже работаете с выводом ~, вам нужно добавить его к 256, а не вычитать. - person user2357112 supports Monica; 03.05.2018
comment
Если вы возьмете число, скажите -12. В двоичном формате это 11110100. Если вы затем конвертируете 11110100 в беззнаковое целое число, вы получите 244. Я где-то ошибся? - person jmkmay; 03.05.2018