不使用STRUCT

时间:2016-12-09 18:32:20

标签: python

我正在尝试编写我的“个人”(不使用任何模块或函数:struct,float ....,int ....,...)根据WIKIPEDIA的STL二进制文件阅读器的python版本:二进制STL文件包含:

  • 80个字符(字节)headern,通常被忽略。

  • 一个4字节的无符号整数,表示文件中三角形面的数量。

  • 每个三角形由12个32位浮点数描述:三个用于法线,然后三个用于每个顶点的X / Y / Z坐标 - 就像STL的ASCII版本一样。在这些之后是一个2字节(“短”)无符号整数,即“属性字节计数” - 在标准格式中,这应该为零,因为大多数软件都不理解其他任何东西。 (((3 + 3 + 3)+3)* 4 + 2 =每个点50个字节)

- 浮点数表示为IEEE浮点数,并假设为小端 -

在两个救世主的帮助下,我发现了无符号整数的存储方式,我可以用3种方法(手工计算)计算出文件中三角形面的数量:

def int_from_bytes(inbytes): # ShadowRanger's
     res = 0
     for i, b in enumerate(inbytes):
         res |= b << (i * 8)  
     return res

def int_from_bytes(inbytes): # ShadowRanger's
    res = 0
    for b in inbytes:
        res <<= 8  # Adjust bytes seen so far to make room for new byte
        res |= b   # Mask in new byte
    return res

def unsigned_int(s): # Robᵩ's
    result = 0
    for ch in s[::-1]:
        result *= 256
        result += ch
    return result

现在我必须转换文件的其余部分(列表中的第3项):浮点数

对于第一个点,50个字节是:

b'\x9a'b'\xa3' b'\x14' b'\xbe' b'\x05' b'$' b'\x85' b'\xbe' b'N' b'b'  
b't' b'?' b'\xcd' b'\xa6' b'\x04' b'\xc4' b'\xfb' b';' b'\xd4' b'\xc1' 
b'\x84' b'w' b'\x81' b'A' b'\xcd' b'\xa6' b'\x04' b'\xc4' b'\xa5' b'\x15' 
b'\xd3' b'\xc1' b'\xb2' b'\xc7' b'\x81' b'A' b'\xef' b'\xa6' b'\x04' 
b'\xc4' b'\x81' b'\x14' b'\xd3' b'\xc1' b'Y' b'\xc7' b'\x81' b'A' b'\x00' 
b'\x00' 

如何手动转换,表示的原理是什么,我应该知道手动转换的规则(某些字节不以\ x开头)。 ?

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

像这样:

def int_from_bytes(inbytes):
    res = 0
    shft = 0
    for b in inbytes:
        res |= ord(b) << shft
        shft += 8
    return res

def float_from_bytes(inbytes):
    bits = int_from_bytes(inbytes)
    mantissa = ((bits&8388607)/8388608.0)
    exponent = (bits>>23)&255
    sign = 1.0 if bits>>31 ==0 else -1.0
    if exponent != 0:
        mantissa+=1.0
    elif mantissa==0.0:
        return sign*0.0
    return sign*pow(2.0,exponent-127)*mantissa


print float_from_bytes('\x9a\xa3\x14\xbe')
print float_from_bytes('\x00\x00\x00\x40')
print float_from_bytes('\x00\x00\xC0\xbf')

输出:

-0.145155340433
2.0
-1.5

格式为IEEE-754浮点。试试这个,看看每个位的含义:https://www.h-schmidt.net/FloatConverter/IEEE754.html