2010-12-12 347 views
1

我有一个二进制文件,其内容定义如下:(所有数据以小端(即最低有效字节在前)存储 )。下面的例子数字是十六进制十六进制和十进制转换

11 63 39 46    --- Time, UTC in seconds since 1 Jan 1970. 
01 00     --- 0001 = No Fix, 0002 = SPS 
97 85 ff e0 7b db 4c 40 --- Latitude, as double 
a1 d5 ce 56 8d 26 28 40 --- Longitude, as double 
f0 37 e1 42    --- Height in meters, as float 
fe 2b f0 3a    --- Speed in km/h, as float 
00 00 00 00    --- Heading (degrees ?), as float 
01 00     --- RCR, log reason. 0001=Time, 0004=Distance 
59 20 6a f3 4a 26 e3 3f --- Distance in meters, as double, 
2a      --- ? Don't know 
a8      --- Checksum, xor of all bytes above not including 0x2a 

从“十六进制”二进制文件中的数据如下

"F25D39460200269652F5032445401F4228D79BCC54C09A3A2743B4ADE73F2A83" 

我很感激,如果你可以根据之前的指令支持我这个数据线转换。

+0

尽管指令的格式不正确,但内容似乎很清楚(当然除了倒数第二个字节)。描述中有什么具体问题? – 6502 2010-12-12 21:17:43

回答

1

可能是错的,但这里的一口吧使用Ruby:

hex = "F25D39460200269652F5032445401F4228D79BCC54C09A3A2743B4ADE73F2A83" 
ints = hex.scan(/../).map{ |s| s.to_i(16) } 
raw = ints.pack('C*') 
fields = raw.unpack('VvEEVVVvE') 

p fields 
#=> [1178164722, 2, 42.2813707974677, -83.1970117467067, 1126644378, 1072147892, nil, 33578, nil] 

p Time.at(fields.first) 
#=> 2007-05-02 21:58:42 -0600 

我会很感激,如果有人非常精通#pack#unpack会告诉我一个更好的方式来完成的前三行。

+0

我不确定其他的价值,但我相信时间是正确的。你是怎么做到的。在vb.net或C#中有任何代码可以理解。谢谢大家的支持。 – 2010-12-13 19:02:36

+0

@waleednosir 1.将每个十六进制字符对转换为整数值。 2.从所有这些整数中创建一个原始字节数组,将它们视为无符号字节。 3.将前四个字节('V')提取为一个无符号的小尾数long。 4.将这些视为时代。 – Phrogz 2010-12-13 19:07:32

+0

非常感谢,它的工作原理。再次感谢 。但我不明白你是如何将整数值1178164722转换为时间和日期的。此外,为什么你已经读取第一个HEX值反向转换为INTeger。我的意思是值1178164722是46395DF2的十进制值,而我的代码的前4个字节是相反的,即F25D3946。请注意,你的结果是确定的,但我不明白为什么。还有,在VB.net或C#中有没有简单的代码能够做到这一点。 。你已经用三行代码解决了它。那真是太神奇了。 – 2010-12-13 20:59:30

0

我的Cygnus Hex Editor可能会加载这样的文件,并使用结构模板以其原始格式显示数据。

除此之外,它只是通过解决每个字节的值来完成每个字节的翻译。

+0

抱歉,我没有相信每个问题的接受或拒绝途径。这是我的错 。我已经接受了你的天才答案和灵感。不要拖延 – 2010-12-26 15:21:19

相关问题