在python中使用pack时,它会在打包长变量时截断我的MSB位,

时间:2018-06-08 01:14:43

标签: python python-packaging

    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字节,这是数据的实际长度。有人可以告诉我发生了什么,并帮助我获得big-endian打包数据中的所有64位

  
    
      
        

原始值:(11111111,22222222,66666666,333333333,44444444,55555555)         Format_string:>我,我,我,我         用途:24字节
        Packed_value:111111112222222266666666333333334444444455555555

      
    
  

1 个答案:

答案 0 :(得分:0)

格式说明符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位中较快的一个。所以,如果你试图匹配一些定义为使用int的Unix API的结构,你必须使用I;一个定义为使用long的结构,你必须使用L;将它们混合起来,你的代码将无法在不同系统之间移植。

如果你想知道为什么qlong long的缩写 - 它对于“四元组”来说确实很短,至少是间接的。最有可能的是,它来自各种不同的Unix系统,使用q作为非标准64位类型的printf格式说明符前缀(所以%qd表示打印为64位int十进制数)。如果没有,它可能来自Windows,使用QWORD表示两个32位整数的64位结构。在两种情况下,“q”表示“quad”-16位是一个字,32位是双字,64位是四(ruple)字。 (在printf的情况下,也可能只有很多单字母前缀可供使用。后来,C和POSIX标准通过允许多字母前缀来解决这个问题,所以它现在是{ {1}},其中 %lld的缩写。)