C# BitConverter в Python

204
19 мая 2018, 10:30

C#:

byte[] b_array; //0x1314FFAAF810
byte[] bytes = new byte[] { b_array[i*2], b_array[i*2+1] };
Int16 toint = BitConverter.ToInt16(bytes, 0);

Python:

b_array = bytearray([0x1314FFAAF810])

Вопрос: как вот 13,14,FF... из массива конвертировать в int16 в Python

Answer 1

В Python для этих целей надо использовать модуль struct.

import struct
from binascii import unhexlify
s = '1314FFAAF810'
size = 2  # int16 (код 'h' для unpack)
bs = unhexlify(s)  # 1314FFAAF810 -- > b'\x13\x14\xff\xaa\xf8\x10'
print(*struct.unpack(len(bs) // size * 'h', bs))  # --> 5139 -21761 4344
Answer 2

Если у вас на входе 6 байт и вы хотите интерпретировать их как 16+-битовые целые числа со знаком с системным порядком байтов (signed short):

>>> import array
>>> a = array.array('h')
>>> a.frombytes(b'\x13\x14\xff\xaa\xf8\x10')
>>> a
array('h', [5139, -21761, 4344])

Если на входе hex-строка, то легко можно соответствующие байты получить:

>>> bytes.fromhex('1314FFAAF810')
b'\x13\x14\xff\xaa\xf8\x10'

Если на входе Python int:

>>> n = 0x1314FFAAF810 
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big')
b'\x13\x14\xff\xaa\xf8\x10'
Answer 3
t1 = '0x1314FFAAF810'
t2 = int(t1, 16)

только предупреждаю, Python не имеет типа Int16, Вы сразу получите целое число таким, как оно есть

Answer 4

C# реализация на базе вашего примера

public static byte[] StrToByteArray(string str)
{
    Dictionary<string, byte> hexindex = new Dictionary<string, byte>();
    for (int i = 0; i <= 255; i++)
        hexindex.Add(i.ToString("X2"), (byte)i);
    List<byte> hexres = new List<byte>();
    for (int i = 0; i < str.Length; i += 2)
        hexres.Add(hexindex[str.Substring(i, 2)]);
    return hexres.ToArray();
}
public static void Main()
{
    byte[] b_array = StrToByteArray("1314FFAAF810");
    for (int i = 0; i < b_array.Length / 2; ++i)
    {
        byte[] bytes = new byte[] { b_array[i * 2], b_array[i * 2 + 1] };
        Int16 toint = BitConverter.ToInt16(bytes, 0);
        Console.WriteLine(toint + " ");
    }
    Console.ReadLine();
}

Программа будет иметь следующий вывод

5139, -21761, 4344

Можем заметить, что BitConverter при преобразовании hex числа 0x1314 поменял местами байты при преобразовании, так как 0x1413 = 5139

Python реализация

Вот код на Python, который делает тоже самое

t1 = '0x1314FFAAF810'
step = 4
i = 2
while i < len(t1) :
    lows = t1[i : i + 2]
    bigs = t1[i + 2 : i + 4]
    x = int(bigs + lows, 16)
    if x > 0x7FFF:
        x = -(0xFFFF - x + 1)
    print x
    i = i + step            

Программа будет иметь идентичный вывод выводу C#

5139, -21761, 4344

Здесь мы извлекаем из строки последовательно байты и перед преобразованием меняем их местами, чтобы сохранить поведение C#.

Пример работы скрипта: https://pyfiddle.io/fiddle/cfadab0f-1f4f-4730-a03f-2474bc29be1d/?i=true

READ ALSO
Binding вложенному свойству

Binding вложенному свойству

Приведу пример кода:

199
С# Удалить блок текста заключенный в фигурные скобки с условием

С# Удалить блок текста заключенный в фигурные скобки с условием

Есть лог файл в json форматеМне необходимо удалить лишние строки заключенные в фигурные скобки в которых есть "processName": "GM_Scheduler"

214
Аутентификация сторонних сервисов

Аутентификация сторонних сервисов

Всем привет, у меня имеется клиент серверное приложение на приложение на Aspnet core помимо основного проекта, появилась необходимость добавить...

208
Ошибка MailKit.Security.SslHandshakeException C#

Ошибка MailKit.Security.SslHandshakeException C#

Есть служба, которая мониторит почту, в случае когда приходит письмо, получает вложения и дальше с ними работаетВо время разработки и тестирования...

290