探索 GoogleGears Wi-Fi 地理定位秘密






4.93/5 (41投票s)
这是一个 C# 应用程序,它使用 Google 定位服务通过 Wi-Fi 热点检索位置信息。
故事
我从一个朋友那里得知了 Google Latitude,当时我买了一部 HTC 手机。在使用了一两次后,我将 ROM 更新为定制 ROM,其中没有安装 Google Latitude 应用。故事开始于我偶然发现我的 iGoogle 上的 Google Latitude 小部件竟然显示了我的位置,尽管我最近并没有用手机访问过 Google Latitude。我搜索了 Google Gears 的地理定位功能,发现它们仅通过 Wi-Fi 热点就能确定你的位置。接下来的内容将讨论 Google Gears 的地理定位功能以及它可能如何工作的设想。我开发了一个工具作为概念验证,展示了如何使用一个简单的 C# 应用程序直接进行 Wi-Fi 地理定位。
引言
本文分为两个部分。第一部分是关于 Google 如何仅凭本地 Wi-Fi 获取地理位置的调查和猜想!第二部分是编码部分,我们将创建一个使用 Google 服务获取地理位置的应用程序。
背景
首先,尝试将你的电脑连接到有线网络——不使用 Wi-Fi——然后尝试使用 Google Latitude 查找你的位置。Google 会显示“未知位置”,因为它无法确定你的位置。将同一台电脑切换到 Wi-Fi 连接,然后再次使用 Google Latitude。现在结果将完全不同——Google 可以给出你位置的精确坐标。这意味着位置不能仅通过 IP 地址来确定。使用 IP,如果你知道 ISP 如何在地理上分配其 IP 地址,你可以知道国家、城市和地区。
我听说的第二件事是,BBC 提供一项服务,可以根据你的位置信息提供天气预报,而这个位置信息是从 Google Gears 获取的。我决定使用 Fiddler 等工具监控 HTTP 流量。我当时在寻找:
- 为了确定我的位置,从我的 PC 检索了哪些数据?
- BBC 如何通过我的 PC 与 Google 定位服务通信?
BBC 天气网站下载 JavaScript 到我的 PC,然后在本地调用 Google Gears,接着 Google 计算我的位置并将它发送到 BBC 网站。下图显示了这些信息。我们可以看到,Google Gears 收集了从我的 PC 检测到的所有 Wi-Fi 热点信息,格式为:{ mac_address , signal_strength, SSID}。
这些数据以 JSON 格式发送到 www.google.com/loc/json,Google 会回复我的纬度、经度,甚至我的地址。发送到 Google 的以上信息足以大致确定你相对于这些 Wi-Fi 热点的位置,但要确定绝对位置,你需要知道这些 Wi-Fi 热点的绝对位置!!同样,Google 如何知道这些信息对我来说还不清楚。我做了一些进一步的调查,发现在有 GSM 数据的情况下,这些数据也会与 Wi-Fi 信息一起发送。
Google Gears 地理定位器是如何工作的?
从这里开始,我将根据上述信息尝试描述 Google 可能如何使用这些信息来提供位置信息。在 GPS 的情况下,发送给 Google 的数据包含:
- GPS 数据
- GSM 热点
- Wi-Fi 热点
对于支持 GPS 的手机来说,仅凭 GSM 热点就足以确定准确的位置信息。这些信息作为请求的一部分发送给 Google。但正如我们所见,这些信息已经包含了地理位置,所以 Google 可能会这样做:
- 计算你的位置 [纬度和经度]。
- 使用 Wi-Fi 数据计算你相对于每个 Wi-Fi 的相对位置。
- 根据 a 和 b 计算每个 Wi-Fi 热点的绝对位置。
- 手机的绝对位置已知。
- 手机到 Wi-Fi 的相对位置已知。
现在,Google 会将 mac_address 和 SSID 以及绝对位置存储在一个地理数据库中,并在可能的情况下保持更新。
如果你打开笔记本电脑并连接到 Google Latitude,Google 可以仅通过 Wi-Fi 热点来确定你的绝对位置,因为它已经从你和其他人的查询中知道 Wi-Fi 热点的绝对位置。正如我们在下图中所看到的,蓝色的用户发送了 GPS、GSM 热点信息和 Wi-Fi 热点信息。Google 计算了 Wi-Fi 热点信息。现在绿色的用户可以通过仅查询 Google 的 Wi-Fi 热点来了解自己的位置。
这并不那么容易。我们需要考虑许多挑战,例如相似的 Wi-Fi 名称、变化的 MAC 地址、Wi-Fi 的开关等。
让我们来制作我们的应用程序
我在这里制作的桌面应用程序是一个 POC,非常简单。它分两步工作:
- 从 PC 获取 Wi-Fi 数据。
- 将此信息发送给 Google 并等待响应。
第一部分可以使用一个有用的库来访问 C# 中的 Wi-Fi 信息。
获取 Wi-Fi 适配器
Json = @"{ ""host"" : ""Test"",
""radio_type"" : ""unknown"",
""request_address"" : true,
""version"" : ""1.1.0"",
""wifi_towers"" : [ ";
lstWifi.Items.Clear();
WlanClient wLanClient = new NativeWifi.WlanClient(); // Get Wifi Interface
if (wLanClient.Interfaces.Length == 0)
{
MessageBox.Show("No Wifi Interfaces found.");
return;
}
Wlan.WlanBssEntry[] lstWlanBss = wLanClient.Interfaces[0].GetNetworkBssList();
if (lstWlanBss == null)
{
MessageBox.Show("No networks has been detected.");
return;
}
枚举可用的 Wi-Fi 热点并拼接 JSON 字符串。
System.Text.StringBuilder SB = new StringBuilder();
foreach (var oWlan in lstWlanBss )
{
ListViewItem lstItem = lstWifi.Items.Add(
System.Text.Encoding.UTF8.GetString(oWlan.dot11Ssid.SSID));
lstItem.SubItems.Add(CalculateSignalQuality(oWlan.linkQuality).ToString());
string MAC = ConvertToMAC(oWlan.dot11Bssid);
lstItem.SubItems.Add(MAC);
SB.Append(@"{""mac_address"" :""");
SB.Append(MAC);
SB.Append(@"""");
SB.Append(@", ""signal_strength"" :");
SB.Append(CalculateSignalQuality(oWlan.linkQuality).ToString());
SB.Append(@", ""ssid"" : """);
SB.Append(System.Text.Encoding.UTF8.GetString(oWlan.dot11Ssid.SSID, 0,
(int)oWlan.dot11Ssid.SSIDLength));
SB.Append(@""" },");
}
Json += SB.ToString().Substring(0, SB.Length - 1); // copy all except last ","
Json += "]}";
textSent.Text = Json;
第二部分是构建一个 HTTP 请求并解析响应。
HttpWebRequest request =
(HttpWebRequest)HttpWebRequest.Create(@"http://www.google.com/loc/json");
request.ContentType = "application/json; charset=utf-8";
request.Accept = "application/json, text/javascript, */*";
request.Method = "POST";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(textSent.Text);
}
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
string json = "";
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
json += reader.ReadLine();
}
}
txtResponse.Text = json;
ParseLocation(json);
关注点
如果 Wi-Fi 部分对你不起作用,如果你没有 Wi-Fi,你仍然可以通过编辑请求文本来检索不同的位置来使用该应用程序。
免责声明
以上 Google 技术只是我基于简单证据和逻辑思考的猜测。本文描述了我的分析性思维以及我如何推导出这项技术,这项技术可能部分或全部不准确。
有用链接
- http://www.wenzk.com/archives/270
- http://tinisles.blogspot.com/2009_12_01_archive.html
- Google Geolocation API: http://code.google.com/p/gears/wiki/GeolocationAPI
- Google Geolocation API Network Protocol: http://code.google.com/apis/gears/geolocation_network_protocol.html
- "Wi-Fi geolocation from carrier-managed system geolocation of a dual mode device", by Cary FitzGerald: http://www.google.com.au/patents?vid=USPATAPP11504920
- Google Mobile Help: http://www.google.com/support/mobile/bin/topic.py?hl=en&topic=15483
- Finding a nearby Wi-Fi router or wireless access point MAC addresses, by GoogleGear: http://test-geolocation.appspot.com/
- Skyhook Wireless: How it works (looks like Google moved one step forward than this by without needing to scan the area by Google employees): http://www.skyhookwireless.com/howitworks/
Modified on Tuesday, March 23, 2010 5:07 AM