2010-12-12 567 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