В python при использовании pack он усекает мои биты MSB при упаковке длинной переменной, - PullRequest
0 голосов
/ 08 июня 2018
    int1 = 11111111
    int2 = 22222222
    long1 = 6666666666666666   
    int3 = 33333333
    int4 = 44444444
    int5 = 55555555
    pack_list = (int1,int2,long1,int3,int4,int5)     
    pack_format = struct.Struct('> I I L I I I')              
    pack_data = pack_format.pack(*pack_list)   

    print "Original_values:", pack_list    
    print "Format_string:", pack_format.format     
    print "Uses:", pack_format.size,'bytes'   
    print "Packed_value:", binascii.hexlify(pack_data) 

У меня есть 64 бита в длинной переменной, но когда я упаковываю, используя big-endian, он обрабатывает его как целое число, которое вы можете увидеть в выводе, показывая как 24 байта вместо 28 байтов, что является фактической длинойданные.Может кто-нибудь сказать мне, что происходит, и помочь мне получить все 64 бита в упакованных данных с прямым порядком байтов

Исходные значения: (11111111, 22222222, 66666666,33333333, 44444444, 55555555) Формат_строки:> IILIII
Использование: 24 байта
Упакованное_значение: 111111112222222266666666333333334444444455555555

1 Ответ

0 голосов
/ 08 июня 2018

Спецификатор формата L означает C long, который обычно составляет 32 бита - того же размера, что и C int.Таким образом, ваш 64-битный номер слишком велик, чтобы соответствовать.(Я почти уверен, что Python 2.7 и 3.x должны давать вам OverflowError или ValueError или что-то еще, а не усекать молча… но, во всяком случае, это не сработает.)

Спецификатор формата Q означает C long long, который обычно составляет 64 бита, так что это тот, который вам нужен.

В случае, если вам интересно, почему в Python есть и I, и L, когда они означают одно и то же - ну,это действительно просто потому, что у C есть и int, и long, но для этого есть, или, по крайней мере, раньше.В настоящее время int почти всегда 32-битный, но когда Python изначально был написан, обычно это было то, что из 16 или 32-битных было быстрее на вашей платформе.Итак, если вы пытались сопоставить структуру из какого-то Unix API, определенного для использования int, вам пришлось использовать I;структура, определенная для использования long, вы должны были использовать L;смешайте их, и ваш код не будет переносимым между различными системами.

И если вам интересно, почему q - это сокращение от long long - это действительно сокращение от «quad», по крайней мере косвенно.Скорее всего, это происходит из множества различных систем Unix, использующих q в качестве префикса спецификатора формата printf для своих нестандартных 64-битных типов (поэтому %qd означает 64-битное целое число, печатаемое как десятичное число).Если нет, то, вероятно, это происходит из Windows, использующей QWORD для 64-битной структуры из двух 32-битных целых.В обоих случаях «q» означало «четыре» - 16 бит - это слово, 32 бита - двойное слово, а 64 бита - четверное (руплевое) слово.(В случае printf также может быть уместно, что было только так много однобуквенных префиксов, чтобы обойти. Позже, стандарты C и POSIX обошли это, просто разрешив многобуквенные префиксы, так что теперь это %lldкоторый является коротким для long long.)

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