Как преобразовать bytearray в Python 2.7 в десятичную строку? - PullRequest
0 голосов
/ 08 января 2019

У меня есть следующий байтовый массив

>>> string_ba
bytearray(b'4\x00/\t\xb5')

, который легко конвертируется в шестнадцатеричную строку со следующими 2 строками:

hex_string = [chr(x).encode('hex') for x in string_ba]
hex_string = ''.join(hex_string)

которые возвращают

>>> hex_string.lower()
'34002f09b5'

что ожидается. (Это подпись карты RFID)

Я конвертирую это в десятичное число, выполнив вышеизложенное, а затем преобразую из шестнадцатеричной строки в десятичную строку (дополненную нулями) со следующей строкой. У меня есть ограничение в 10 символов в строке, поэтому я вынужден удалить первые 2 символа в строке, чтобы иметь возможность преобразовать его не более чем в 10 десятичных знаков.

dec_string = str(int(hex_string[2:], 16)).zfill(10)
>>> dec_string
'0003082677'

что верно, так как я проверял это с помощью онлайн-конвертера (hex: 002f09b5, dec: 3082677) Вопрос в том, если есть способ пропустить преобразование из bytearray в hex_string, чтобы получить десятичную строку. Другими словами, чтобы перейти прямо от bytearray к dec_string

Это будет работать на Python 2.7.15.

>>> sys.version
'2.7.15rc1 (default, Apr 15 2018, 21:51:34) \n[GCC 7.3.0]'

Я попытался удалить первый элемент из bytearray, а затем преобразовать его в строку напрямую и соединить. Но это не дает желаемого результата.

string_ba = string_ba[1:]
test_string = [str(x) for x in string_ba]
test_dec_string = ''.join(test_string).zfill(10)

>>> test_dec_string
'0000479181'

Чтобы повторить вопрос, есть ли способ перейти прямо от байта к десятичной строке

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Число (назовем его X ), состоящее из n цифр (в базе давайте обозначим его как B ) записывается как:

D п-1 D п-2 D * * п тысяча двадцать-один-3 * * ... 1 022 D 2 D 1 D 0 (где каждый D i является цифрой в базе B )

и его значение можно вычислить по формуле:

V X = Σ i n = - 0 1 (B i * D i ) (обратите внимание, что в этом примере число пересекается справа налево - смысл перемещения не влияет на конечное значение).

Например, число 2468 (B 10 ) = 10 0 * 8 + 10 1 * 6 + 10 2 * 4 + 10 3 * 2 ( = 8 + 60 + 400 + 2000 ).

An ASCII string на самом деле число в базе 256 ( 0x100 ) , где каждый символ (байт) - это цифра.

Вот альтернатива, основанная на вышеупомянутом:

  • Он выполняет только математические операции над целыми числами (преобразование в строку выполняется только в конце)
  • Смысл обхода (сверху) полезен с ограничением (конечное (десятичное) число должно соответствовать количеству цифр, а в случае переполнения наиболее значимые из них должны игнорироваться )
  • Алгоритм прост: начиная справа, вычисляет значение частичного числа, до достижения максимально допустимого значения или исчерпывая цифры (строковые символы)

code.py

#!/usr/bin/env python

import sys 


DEFAULT_MAX_DIGITS = 10


def convert(array, max_digits=DEFAULT_MAX_DIGITS):
    max_val = 10 ** max_digits
    number_val = 0
    for idx, digit in enumerate(reversed(array)):
        cur_val = 256 ** idx * digit
        if number_val + cur_val > max_val:
            break
        number_val += cur_val
    return str(number_val).zfill(max_digits)


def main():
    b = bytearray("4\x00/\t\xb5")
    print("b: {:}\n".format(repr(b)))
    for max_digits in range(6, 15, 2):
        print("Conversion of b (with max {:02d} digits): {:}{:s}".format(
            max_digits, convert(b, max_digits=max_digits),
            " (!!! Default case - required in the question)" if max_digits == DEFAULT_MAX_DIGITS else ""
        ))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main() 

Outpput

(py_064_02.07.15_test0) e:\Work\Dev\StackOverflow\q054091895>"e:\Work\Dev\VEnvs\py_064_02.07.15_test0\Scripts\python.exe" code.py
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32

b: bytearray(b'4\x00/\t\xb5')

Conversion of b (with max 06 digits): 002485
Conversion of b (with max 08 digits): 03082677
Conversion of b (with max 10 digits): 0003082677 (!!! Default case - required in the question)
Conversion of b (with max 12 digits): 223341382069
Conversion of b (with max 14 digits): 00223341382069
0 голосов
/ 08 января 2019

Вы можете использовать библиотеку структур для преобразования байтового массива в десятичный. https://codereview.stackexchange.com/questions/142915/converting-a-bytearray-into-an-integer возможно, поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...