dbroot.v5文件详解

dbRoot.v5是GE的主要的配置文件,其中包括层列表,提供程序列表(图层和快照的内容提供程序),图层的显示样式,可能的服务器列表(天空,火星等),当前数据库版本和当前密钥,用于解密所有传输的数据。

目前,这个文件可以以两种格式传输(有条件:第一版和第二版),二进制结构不同,但最后携带相同的数据:

  • 适用于5.1及以下客户(较小版本的客户) - 第一版
  • 对于5.2及更早版本的客户(旧版客户端) - 第二版

此外,客户端5.2.1.1329(来自标尺5.2的第一个客户端)以及稍后支持该文件的两个版本(第二个版本是默认版本,第一个版本仅在第二个版本文件不可用时加载)。

首先从服务器请求此文件。如果无法从Internet下载此文件,则客户端会尝试从缓存中下载该文件(第一版文件存储在dbCache.dat中,第二版存储在dbroot_cache中)。在这种情况下,如果客户端无法从缓存中下载它(例如,缓存为空),则客户端的工作将被中断,并且将报告无法连接到服务器。

每次客户端启动时都会下载此文件(对于Sky,Mars和History服务器 - 每次会话一次,切换到此模式时)。

请求格式

客户端生成此文件请求的方式取决于Windows语言设置,GoogleEarth自己的设置,以及客户端的旧版本以及客户端的版本和类型。地球视图模式的典型查询示例:

 请求第一版文件:http://kh.google.com/dbRoot.v5?hl=ru-RU&gl=ru第二版的文件请求:http://kh.google.com/dbRoot.v5?hl=ru-RU&gl=ru&output=proto&cv=5.2.1.1329&ct=free其中,hl = ru-RU是用户的语言gl = ru  - 用户的位置output = proto  - 容器格式cv = 5.2.1.1329  - 客户端版本ct =免费 - 客户类型(免费/专业版)

关键

解密数据的密钥从第9个字节开始,长度为1016个字节。为了在解密算法中使用,必须补充8个零(在前面)到1024个字

原文地址:https://greverse.bitbucket.io/dbroot.htm

相关代码:python 代码地址

 

import os, sys, requests, struct, zlib# urls:
# kh.google.com/dbRoot.v5 < 秘钥和地图版本信息
# kh.google.com/flatfile?q2-0-q.705 < QTree数据
# kh.google.com/flatfile?f1-030-i.704 < 瓦片图像
# /dbRoot.v5?hl=zh-hans-cn&gl=cn&output=proto&cv=5.2.1.1588&ct=free
# 1. def Eval(fname, key):# 解码数据if (os.path.exists(fname)==False): return Noneif (os.path.getsize(fname)==0): return Nonef = open(fname, 'rb+')data = f.read()                             # 读取文件内容f.close()#outdata = [0 for i in range(len(data))]    # 创建一个结果数组outdata = bytearray(len(data))              # 创建一个结果数组index = 16for i in range(0, len(data)):outdata[i] = ord(data[i]) ^ ord(key[index+8])index += 1if (index % 8 == 0): index += 16if (index >= 1016): index = (index + 8) % 24return outdatadef EvalData(data, key):# 解码数据outdata = bytearray(len(data))              # 创建一个结果数组index = 16for i in range(0, len(data)):outdata[i] = ord(data[i]) ^ ord(key[index+8])index += 1if (index % 8 == 0): index += 16if (index >= 1016): index = (index + 8) % 24return outdatadef ReadKEY(fname):# 读取KEY文件f = open(fname, 'rb+')data = f.read()f.close()return datadef ReadVersion(fname):# 读取dbRoot.v5文件里的版本号if (os.path.exists(fname)==False): return Noneif (os.path.getsize(fname)==0): return Nonef = open(fname, 'rb+')f.seek(6)value = f.read(2)f.close()version = struct.unpack('h', value)[0]version = version ^ 0x4200return versiondef ReadDBRoot():# 读取dbRoot.v5文件# 详细说明 http://greverse.bitbucket.org/dbroot.htm# 00-03: 固定 9464874E# 04-05: 数据版本 6600# 06-07: 地图版本 比如 C240 需要与 0x4200 进行异或运算得出最终版本# 08-1023: 数据秘钥共1016字节# 1024-: 加密的XML数据passdef Tile2QuadKEY(tileX, tileY, zoom):# 瓦片坐标转四叉树result = '0'for i in range(zoom, 0, -1):digit = 0mask = 1 << (i - 1)if ((tileX & mask) != 0): digit += 1if ((tileY & mask) != 0): digit += 2# 由于谷歌四叉树算法和必应四叉树算法不一致# 所以取巧采用对照表的方法可以解决 但第一位始终是0# 对照表# 必应 -> 谷歌# 0 -> 3# 1 -> 2# 2 -> 0# 3 -> 1if (digit == 0): result += '3'elif (digit == 1): result += '2'elif (digit == 2): result += '0'elif (digit == 3): result += '1'return resultdef QuadKEY2Tile(nums):# 四叉树转 反转的时候也必须通过对照表tileX = 0tileY = 0nums = nums[1:]       # 第一位是0所以取掉zoom = len(nums)for i in range(zoom, 0, -1):mask = 1 << (i - 1)if (nums[zoom - i] == '3'):continueelif (nums[zoom - i] == '2'):tileX |= maskcontinueelif (nums[zoom - i] == '0'):tileY |= maskcontinueelif (nums[zoom - i] == '1'):tileX |= masktileY |= maskcontinuereturn tileX, tileY, zoomdef Hex2Time(data):# 十六进制转时间# data: 传入16进制数据month = int(data & 0xF)         # 月day = int((data & 0x1F0)>>4)    # 日year = int((data & 0xFFE00)>>9) # 年return year, month, daydef Time2Hex(year, month, day):# 时间转十六进制passif __name__ == '__main__':print '[==DoDo==]'print 'GE Tiles.'print 'Encode: %s' %  sys.getdefaultencoding()# 解密瓦片数据#keydata = ReadKEY('data/key.bin')#imgdata = Eval('data/_flatfile-f1c-0201202-t.705', keydata)#f = open('out.jpg', 'wb')#f.write(imgdata)#f.flush()#f.close()# 时间字符串转时间#Hex2Time(int('0xfa99b', 16))# 瓦片坐标和四叉树互转#print Tile2QuadKEY(3, 5, 3)#print 'X:%s Y:%s Z:%s' % QuadKEY2Tile('0201202')# 读取地图版本#print ReadVersion('data/dbRoot.v5')# 解码QTree数据keydata = ReadKEY('data/key.bin')zlibdata = Eval('data/_flatfile-q2-0-q.706', keydata)f = open('data.z', 'wb')    # 解密后的压缩数据f.write(zlibdata)f.flush()f.close()unzlibdata = zlib.decompress(str(zlibdata[8:]))f = open('data.u', 'wb')    # 解压后的真实数据f.write(unzlibdata)f.flush()f.close()'''# 下载L2级别影像进行测试keydata = ReadKEY('data/key.bin')for x in range(0, 4):for y in range(0, 4):nums = Tile2QuadKEY(x, y, 2)url = 'http://kh.google.com/flatfile?f1-{0}-i.705'.format(nums)response = requests.get(url, stream=True)data = response.raw.read()savefile = 'out/_{0}.dat'.format(nums)f = open(savefile, 'wb')f.write(data)f.flush()f.close()savefile = 'out/{0}.jpg'.format(nums)data = EvalData(data, keydata)f = open(savefile, 'wb')f.write(data)f.flush()f.close()'''print 'OK.'

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部