原始浮点数编码

23

更新: 原问题已经不再适用于此问题,因此我将其放置不管以展示我尝试/学习的内容和背景。很明显,这不仅是一个“Base64变体”,而且还涉及到更多。

背景: 我主要使用Python 3.x编程,主要用于开源程序Blender。我是一名初学者/业余级别的程序员,但我对大型概念有相当好的理解。 我阅读了与我的问题相关的这些文章。

问题: 我有一个二进制文件,其中包含3D网格数据(浮点数列表和整数列表),对应于每个顶点的x、y、z坐标(浮点数)和组成网格面的顶点的索引(整数)。该文件的组织方式类似于xml...

<SomeFieldLabel and header like info>**thensomedatabetween**</SomeFieldLabel>

这是“顶点”字段的示例:
<Vertices vertex_count="42816" base64_encoded_bytes="513792" check_value="4133547451">685506bytes of b64 encoded data
</Vertices>
  1. 在“Vertices”和“/Vertices”之间有685506字节的数据。
  2. 这些字节仅由a-a,A-Z,0-9和+ /组成,这是base64的标准。
  3. 当我获取这些字节并在Python中使用标准的base64decode时,得到513792个字节。
  4. 如果可以相信vertex_count =“42816”,则应该需要42816 * 12字节来表示每个顶点的x,y,z。 42816 * 12 = 513792.非常好。
  5. 现在,如果我尝试将我的解码字节作为32位浮点数解包,我会得到垃圾...因此有些问题。

我认为可能还有一个额外的加密步骤。也许有一个翻译表,旋转密码或某种流密码?奇怪的是字节数是正确的,但结果不是,这应该限制了可能性。有什么想法吗?这里有两个示例文件,文件扩展名已更改为*.mesh。我不想公开这个文件格式,只是想编写一个导入程序,以便我可以在Blender中使用这些模型。

这里有两个示例文件。我从提供公司的“查看器”中提取了来自顶点和面的原始二进制数据(未经过b64解码),并提供了边界框信息。
示例文件1

示例文件2

关于顶点字段的注释

  • 头部指定了顶点数
  • 头部指定了base64编码之前的字节数
  • 头部指定了一个“检查值”,其意义尚未确定
  • 字段中的数据仅包含标准的base64字符
  • 标准base64解码后输出数据的长度为... length = vertex_count*12 = base64_encoded_bytes。有时b64输出中会有4个额外的字节?
  • 编码/解码字节的比率为4/3,这也是典型的base64比率

关于面片字段的注释

  • 头部指定了面片数
  • 头部指定了base64编码之前的字节数

  • base64_encoded_bytes/facet_count的比率似乎相当不同。从1.1到约1.2不等。如果它们被编码为对应于顶点索引的3x4字节整数,我们会期望一个12的比率。所以这个字段要么是压缩的,要么是使用三角形带保存的模型,或者两者都有 :-/

更多调查
我在公司提供的viewer.exe(用十六进制编辑器打开)中打开了这些文件(也是我得到边界框信息的地方)。以下是一些我发现有趣且可能进一步搜索的片段。

f_LicenseClient...Ì.@......m_wApplicationID.....@......f_bSiteEncryptionActive.....@......f_bSaveXXXXXXInternalEncrypted.....@......f_bLoadXXXXXXInternalEncrypted...¼!@......f_strSiteKey....í†......

在LoadXXXXXXInternalEncrypted和SaveXXXXXXInternalEncrypted中,我用XX屏蔽了公司名称。看起来我们绝对有一些加密超出了简单的base64表变化。

SaveEncryptedModelToStream.................Self...pUx....Model...ˆÃC....Stream....

这对我来说看起来像是一个函数定义,用于保存加密模型。

DefaultEncryptionMethod¼!@........ÿ.......€...€ÿÿ.DefaultEncryptionKey€–†....ÿ...ÿ.......€....ÿÿ.DefaultIncludeModelData –†....ÿ...ÿ.......€...€ÿÿ.DefaultVersion.@

啊哈...现在这很有趣。一个默认的加密密钥。请注意,每个描述符之间都有27个字节,它们总是以"ÿÿ"结尾。这里有24个字节,不包括"ÿÿ"。对我来说,这是一个192位的密钥...但是谁知道这24个字节中是否都对应着密钥?你有什么想法吗?

代码片段
为了节省空间,我将此脚本放在我的Dropbox中进行下载。它会读取文件,从顶点和面字段中提取基本信息,并打印出一堆东西。您可以取消注释结尾,使其将数据块保存到单独的文件中以便更轻松地分析。
basic_mesh_read.py

这是我用来尝试所有"合理"变化的标准base64库的代码。 try_all_b64_tables.py


3
你确定编码的值是32位浮点数吗?如果是,它们是用LSB还是MSB表示的? - campos.ddc
这与字节序相同,所以至少这个问题可以排除了。 - campos.ddc
1
它没有加密。加密文本看起来像随机字节,我看到很多重复。 - Maarten Bodewes
1
你有没有获取一些已知明文的方式?如果您知道其中一个顶点的实际值,那么您的工作将变得更容易。 - Rasmus Faber
1
那个 check_value 确实看起来很可疑。我尝试使用它对数据进行异或运算,但结果仍然是无意义的值。所以可能涉及到更复杂的问题。 - Igor Skochinsky
显示剩余15条评论
1个回答

1

我不确定您为什么认为结果不是浮点数。您提供的“解密数据”中的顶点数据包含首个4字节“f2 01 31 41”。根据LSB字节顺序,这对应于位模式“413101f2”,它是浮点值11.062973的IEEE 754表示。该文件中的所有4字节值都在同一范围内,因此我认为它们都是浮点值。


是的,"解密数据"是4字节浮点数。这个特定的数据是由第三方应用程序解密的。因此,原始文件中的数据从原始浮点数->加密->base64编码。我的目标是反向操作。加密->原始浮点数,但我目前还无法做到。当我第一次写这个线程时,我只是认为它是Base64变体,但更深入的调查得出结论,它也被加密了。对于造成的困惑,我表示歉意。 - patmo141
1
也许“加密数据”实际上只是一个二进制浮点数流? - jpaugh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接