我有一些二进制数据流,可通过地理位置坐标-纬度和经度。我需要找到它们编码的方法。
4adac812 = 74°26.2851' = 74.438085
2b6059f9 = 43°0.2763' = 43.004605
4adaee12 = 74°26.3003' = 74.438338
2a3c8df9 = 42°56.3177' = 42.938628
4ae86d11 = 74°40.1463' = 74.669105
2afd0efb = 42°59.6263' = 42.993772
第一个值是十六进制值。第二和第三是我在输出中获得的值(不确定转换中使用了哪个)。
我发现第一个字节代表值的整数部分(0x4a = 74)。但是我找不到小数部分的编码方式。
我将非常感谢您的帮助!
谢谢。
-
Upd:此流通过tcp协议来自某些“中文” gps服务器软件。我没有适合的软件的资料或文档。我想它是用VC ++ 6编写的,并使用了一些标准实现。
-
更新:这是我收到的数据包:
Hex data:
41 00 00 00 13 bd b2 2c
4a e8 6d 11 2a 3c 8d f9
f6 0c ee 13
Log data in client soft:
[Lng] 74°40.1463', direction:1
[Lat] 42°56.3177', direction:1
[Head] direction:1006, speed:3318, AVA:1
[Time] 2011-02-25 19:52:19
Result data in client (UI):
74.669105
42.938628
Head 100 // floor(1006/10)
Speed 61.1 // floor(3318/54.3)
41 00 00 00 b1 bc b2 2c
4a da ee 12 2b 60 59 f9
00 00 bc 11
[Lng] 74°26.3003', direction:1
[Lat] 43°0.2763', direction:1
[Head] direction:444, speed:0, AVA:1
[Time] 2011-02-25 19:50:49
74.438338
43.004605
00 00 00 00 21 bd b2 2c
4a da c8 12 aa fd 0e fb
0d 0b e1 1d
[Lng] 74°26.2851', direction:1
[Lat] 42°59.6263', direction:1
[Head] direction:3553, speed:2829, AVA:1
[Time] 2011-02-25 19:52:33
74.438085
42.993772
我不知道前4个字节是什么意思。
我发现第5个字节的低7位代表秒数。 (也许5-8位是时间?)字节9表示纬度的整数。
字节13是Lng的整数。
字节17-18反转(字字节)就是速度。
字节19-20的字节是ava(?)和方向(4 + 12位)。 (顺便说一句,有人知道什么是ava吗?)
还有一个音符。在第三个数据包的第13个字节中,您只能看到使用的低7位。我想第一位并不代表smth(我一开始就删除了它,对不起,如果我错了)。
我已对您的数据重新排序,以便我们首先拥有3个纬度,然后有3个纬度:
74.438085、74.438338、74.669105、43.004605、42.938628、42.993772
这是我能想到的最适合的十六进制为:
74.437368、74.439881、74.668392、42.993224、42.961388、42.982391
差异为:-0.000717、0.001543,-0.000713,-0.011381、0.022760,-0.011381
从完整的十六进制(4个非3字节)生成这些值的程序是:
int main(int argc, char** argv) {
int a[] = { 0x4adac812, 0x4adaee12, 0x4ae86d11, 0x2b6059f9, 0x2a3c8df9, 0x2afd0efb };
int i = 0;
while(i<3) {
double b = (double)a[i] / (2<<(3*8)) * 8.668993 -250.0197;
printf("%f\n",b);
i++;
}
while(i<6) {
double b = (double)a[i] / (2<<(3*8)) * 0.05586007 +41.78172;
printf("%f\n",b);
i++;
}
printf("press key");
getch();
}
这里集思广益。
[如果我们查看第二个字节的低6位(data [1]&0x3f),对于大多数示例,我们将获得“分钟”值。
0xda & 0x3f = 0x1a = 26; // ok
0x60 & 0x3f = 0; // ok
0xe8 & 0x3f = 0x28 = 40; // ok
0x3c & 0x3f = 0x3c = 60; // should be 56
0xfd & 0x3f = 0x3d = 61; // should be 59
也许这是正确的方向?
我已经尝试过您的新数据包:
74 + 40.1463 / 6074 + 26.3003 / 6074 + 26.2851 / 6042 + 56.3177 / 6043 + 0.2763 / 6042 + 59.6263 / 60
74.66910, 74.43834, 74.43809, 42.93863, 43.00460, 42.99377
我的程序给出:
74.668392, 74.439881, 74.437368, 42.961388, 42.993224, 39.407346
不同之处是:
-0.000708, 0.001541, -0.000722, 0.022758, -0.011376, -3.586424
我重复使用了我从第一个数据包派生的4个常量,因为这些常量可能存储在客户端的某个地方。细微的差异可能是客户端随机进行的结果,以防止您获得确切的值或对他们的协议进行逆向工程。
我有一个32位十六进制字符串的示例:e0ec041c-90d5700d-5cf7ab00经度-纬度-高度
我使用了大约10个从十六进制到十进制的转换器,但没有任何好的结果,看起来像是long / lat。只知道坐标应该在Europet中。
我是Python和R语言的基础,所以,如果您要使用脚本,那么使用这种语言会很棒。
谢谢,安德里[]