GPS数据中的隐秘信息编码

在现代科技中,GPS设备被广泛应用于记录和交换地理位置信息。GPX文件格式是GPS设备用来存储这些信息的标准格式之一。本文将探讨一种新颖的方法,即在GPX文件中隐藏额外的信息。这种方法类似于椭圆曲线密码学中的点编码,通过改变GPS轨迹中的特定经度值来实现信息的编码。

GPX文件结构简介

GPX文件是一种基于XML的格式,用于存储地理数据。它通常包含轨迹点(轨迹或路线)和命名点(航点)。文件结构简单明了,易于理解和操作。

<gpx version="1.0"/> <trk> <name>轨迹</name> <trkseg> <trkpt lat="52.311389" lon="9.787149"> [可选数据] </trkpt> <trkpt lat="52.311276" lon="9.787381"> [可选数据] </trkpt> </trkseg> </trk> <wpt lat="52.310218" lon="9.791205"> <name><![CDATA[地点]]></name> [可选数据] </wpt>

在GPX文件中,纬度和经度的值比常见的接收器更为精确,小数点后第六位的变化意味着10厘米的变化。因此,隐藏额外信息的一个想法是改变最不显著的小数位,这可以看作是一种地理最低有效位(Geo LSB),与像素颜色的最低有效位类似。

编码信息的方法

有一种众所周知的方法可以将任何数据编码为给定曲线上的点。将x轴分成相等的列,对这些列进行编号,然后为每个要编码的值选择相应列中的一个点。对于纯文本消息,甚至可以像下面这样划分地图:

例如,在椭圆曲线密码学中,会进行一些奇怪的计算来处理选定的点。但是,如果熟悉文章,会知道会避免复杂的数学计算。也会从给定的池中选择点,但会保持它们的原样,使它们看起来无害。

运行密钥文件

通常,GPX文件是在行走时记录的,或者在地图上绘制的。人们还会将特殊地点标记为航点。当然,每个航点也是(记录的,不是绘制的)轨迹的一部分:轨迹的作者必须去那里记录航点。这是昨天记录的一些GPS数据。有很多路径和两个航点。

不知道那个区域,对吧?可以把航点放在任何地方。甚至可以发布一个航点文件,加载到GPS设备上——只要周围有漂亮的东西(以防有人真的走到那里),这看起来并不奇怪。这个想法是标记编码消息的航点。根据文本或二进制流,从轨迹中取出点,然后写入空白的航点文件或轨迹的GPX文件。人们可以自由地在地图上查看这些文件或将它们导入到他们的GPS设备上。但是,只有那些解码某些点的经度的人才能看见隐藏的消息。

编码过程

从轨迹中得到的原始坐标是浮点值,小数点后有六位。在能够编码0到255之间的字节值之前,需要以某种方式压缩它们。决定将整个轨迹进行缩放,使得最小的经度为0,最大的为255。这段代码读取XML节点中的点,并获取最小和最大的坐标:

// 查找所有轨迹点节点 XmlNodeList trackPoints = gpxDocument.GetElementsByTagName("trkpt"); // 将节点转换为点 ScalablePoint[] track = GeoNodeToPoints(trackPoints); // 将轨迹移动到左上角 ScaleTrack(track);

以下是将轨迹压缩到255x255矩阵中的代码。也对纬度进行了缩放,因为轨迹将在图片框中显示。

private void ScaleTrack(ScalablePoint[] track) { int scaledMaxLon = maxLon - minLon; int scaledMaxLat = maxLat - minLat; for (int n = 0; n < track.Length; n++) { // 将轨迹移动到左上角 track[n].X -= minLon; track[n].Y -= minLat; // 将轨迹缩放到宽度 = 高度 = 256 = 每列一个可能的消息字节 track[n].X = (int)Math.Round((track[n].X / (float)scaledMaxLon) * 255); track[n].Y = (int)Math.Round((track[n].Y / (float)scaledMaxLat) * 255); } }

当轨迹被缩放到0到255之间的经度时,就可以开始编码了!对于秘密消息的每个字节,取一个具有相应缩放经度的点。然后,将这个点写入航点GPX文件,并上传到一个知名的网站。

解码过程

所以,从一个户外狂热者的网站下载了一个GPX文件。是知道在哪里寻找的人。不是用行程规划器打开它,而是用解码应用程序打开它。这段代码从文件中获取航点,并使用之前用于缩放密钥轨迹的相同参数进行缩放。然后,可以从x值中读取消息。

private void btnDecode_Click(object sender, EventArgs e) { XmlDocument gpxDocument = new XmlDocument(); gpxDocument.Load(fsWaypoints.FileName); XmlNodeList wayPointNodes = gpxDocument.GetElementsByTagName("wpt"); ScalablePoint[] wayPoints = GeoNodeToPoints(wayPointNodes); ScaleTrack(wayPoints); char[] messageChars = new char[wayPoints.Length]; for (int n = 0; n < messageChars.Length; n++) { messageChars[n] = (char)wayPoints[n].X; } txtDecodedMessage.Text = new string(messageChars); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485