iss-spoofing: with real-time correction, cities hearing a signal more than 5% off the recorded speed turn red
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -127,7 +127,7 @@ footer{padding-block:18px 30px;color:var(--faint);font-size:13px}
|
||||
|
||||
<section class="wrap intro">
|
||||
<p><b>Hypothesis.</b> The radio signals attributed to the International Space Station come from ground transmitters along its track, imitating a source that moves at the measured speed, 7.07 km/s.</p>
|
||||
<p><b>Test.</b> The <span class="k-st">station</span> is placed where the published orbit puts it, which is where it is seen to pass at the predicted times (<a href="https://spotthestation.nasa.gov/">Spot the Station</a>); its speed across each map follows from that map's distances. The <span class="k-sig">spoofed signal</span> is the source those transmitters imitate, moving along the same track at 7.07 km/s, lined up with the station at each northbound equator crossing, or at any moment with <i>Line up signal now</i>. A city turns <span class="k-bad">red</span> when the station is above its horizon and the signal is not, or the reverse.</p>
|
||||
<p><b>Test.</b> The <span class="k-st">station</span> is placed where the published orbit puts it, which is where it is seen to pass at the predicted times (<a href="https://spotthestation.nasa.gov/">Spot the Station</a>); its speed across each map follows from that map's distances. The <span class="k-sig">spoofed signal</span> is the source those transmitters imitate, moving along the same track at 7.07 km/s, lined up with the station at each northbound equator crossing, or at any moment with <i>Line up signal now</i>. A city turns <span class="k-bad">red</span> when the station is above its horizon and the signal is not, or the reverse. With <i>Real-time correction</i> it also turns red when the signal it hears moves more than 5% faster or slower than the 7.07 km/s the recordings show, since its Doppler shift would then differ from theirs.</p>
|
||||
</section>
|
||||
|
||||
<div class="bar">
|
||||
@@ -163,7 +163,7 @@ footer{padding-block:18px 30px;color:var(--faint);font-size:13px}
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><path d="M1 7h20" stroke="#ff4fd8" stroke-opacity=".6" stroke-width="3"/></svg>Gap along the track</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="6" fill="none" stroke="#fff" stroke-opacity=".6"/></svg>Above the horizon</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="3" fill="#3dffa0"/></svg>City: station and signal in view</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="3" fill="#ff4d5e"/></svg>City: one without the other</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="3" fill="#ff4d5e"/></svg>City: one without the other, or a signal at the wrong speed</li>
|
||||
</ul>
|
||||
|
||||
<main class="wrap grid">
|
||||
@@ -306,6 +306,8 @@ const SM = {};
|
||||
for (const key of ["ae", "dualpole", "mercator"]) SM[key] = Float64Array.from(D.maps[key].S);
|
||||
let syncT = null, corr = false, latency = 10;
|
||||
const LATENCY = [0, 1, 2, 5, 10, 20, 30, 60, 120, 300];
|
||||
// with real-time correction the signal moves at the map speed; a receiver hears that speed in its Doppler shift
|
||||
const wrongSpeed = (p, M) => corr && p.key !== "globe" && Math.abs(M.vs / VM - 1) > 0.05;
|
||||
function timeAtDistance(arr, km) {
|
||||
let lo = 0, hi = arr.length - 1;
|
||||
if (km <= arr[lo]) return 0;
|
||||
@@ -447,7 +449,7 @@ function drawPanel(p, S, pulse) {
|
||||
}
|
||||
const okP = new Path2D(), badP = new Path2D();
|
||||
for (let j = 0; j < NC; j++) {
|
||||
const s = inView(S.us, j), h = inView(M.ug, j), st = s && h ? 1 : s || h ? 2 : 0;
|
||||
const s = inView(S.us, j), h = inView(M.ug, j), st = s && h ? (wrongSpeed(p, M) ? 2 : 1) : s || h ? 2 : 0;
|
||||
p.state[j] = st;
|
||||
const q = cxy[j];
|
||||
if (!st || !q) continue;
|
||||
@@ -590,6 +592,7 @@ const tip = document.getElementById("tip");
|
||||
const STATE = (p, j) => {
|
||||
if (p.key === "globe") return p.state[j] ? "Station and signal in view" : "Neither in view";
|
||||
const S = lastS, s = inView(S.us, j), h = inView(S.m[p.key].ug, j);
|
||||
if (s && h && wrongSpeed(p, S.m[p.key])) return `Station and signal in view; the signal moves at ×${(S.m[p.key].vs / VM).toFixed(2)} the recorded speed, so its Doppler shift is wrong`;
|
||||
return s && h ? "Station and signal in view" : s ? "Station in view, no signal" : h ? "Signal, no station in view" : "Neither in view";
|
||||
};
|
||||
let lastS = null;
|
||||
|
||||
@@ -127,7 +127,7 @@ footer{padding-block:18px 30px;color:var(--faint);font-size:13px}
|
||||
|
||||
<section class="wrap intro">
|
||||
<p><b>Hypothesis.</b> The radio signals attributed to the International Space Station come from ground transmitters along its track, imitating a source that moves at the measured speed, {{V_SIG}} km/s.</p>
|
||||
<p><b>Test.</b> The <span class="k-st">station</span> is placed where the published orbit puts it, which is where it is seen to pass at the predicted times (<a href="https://spotthestation.nasa.gov/">Spot the Station</a>); its speed across each map follows from that map's distances. The <span class="k-sig">spoofed signal</span> is the source those transmitters imitate, moving along the same track at {{V_SIG}} km/s, lined up with the station at each northbound equator crossing, or at any moment with <i>Line up signal now</i>. A city turns <span class="k-bad">red</span> when the station is above its horizon and the signal is not, or the reverse.</p>
|
||||
<p><b>Test.</b> The <span class="k-st">station</span> is placed where the published orbit puts it, which is where it is seen to pass at the predicted times (<a href="https://spotthestation.nasa.gov/">Spot the Station</a>); its speed across each map follows from that map's distances. The <span class="k-sig">spoofed signal</span> is the source those transmitters imitate, moving along the same track at {{V_SIG}} km/s, lined up with the station at each northbound equator crossing, or at any moment with <i>Line up signal now</i>. A city turns <span class="k-bad">red</span> when the station is above its horizon and the signal is not, or the reverse. With <i>Real-time correction</i> it also turns red when the signal it hears moves more than 5% faster or slower than the {{V_SIG}} km/s the recordings show, since its Doppler shift would then differ from theirs.</p>
|
||||
</section>
|
||||
|
||||
<div class="bar">
|
||||
@@ -163,7 +163,7 @@ footer{padding-block:18px 30px;color:var(--faint);font-size:13px}
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><path d="M1 7h20" stroke="#ff4fd8" stroke-opacity=".6" stroke-width="3"/></svg>Gap along the track</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="6" fill="none" stroke="#fff" stroke-opacity=".6"/></svg>Above the horizon</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="3" fill="#3dffa0"/></svg>City: station and signal in view</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="3" fill="#ff4d5e"/></svg>City: one without the other</li>
|
||||
<li><svg viewBox="0 0 22 14" aria-hidden="true"><circle cx="11" cy="7" r="3" fill="#ff4d5e"/></svg>City: one without the other, or a signal at the wrong speed</li>
|
||||
</ul>
|
||||
|
||||
<main class="wrap grid">
|
||||
@@ -304,6 +304,8 @@ const SM = {};
|
||||
for (const key of ["ae", "dualpole", "mercator"]) SM[key] = Float64Array.from(D.maps[key].S);
|
||||
let syncT = null, corr = false, latency = 10;
|
||||
const LATENCY = [0, 1, 2, 5, 10, 20, 30, 60, 120, 300];
|
||||
// with real-time correction the signal moves at the map speed; a receiver hears that speed in its Doppler shift
|
||||
const wrongSpeed = (p, M) => corr && p.key !== "globe" && Math.abs(M.vs / VM - 1) > 0.05;
|
||||
function timeAtDistance(arr, km) {
|
||||
let lo = 0, hi = arr.length - 1;
|
||||
if (km <= arr[lo]) return 0;
|
||||
@@ -445,7 +447,7 @@ function drawPanel(p, S, pulse) {
|
||||
}
|
||||
const okP = new Path2D(), badP = new Path2D();
|
||||
for (let j = 0; j < NC; j++) {
|
||||
const s = inView(S.us, j), h = inView(M.ug, j), st = s && h ? 1 : s || h ? 2 : 0;
|
||||
const s = inView(S.us, j), h = inView(M.ug, j), st = s && h ? (wrongSpeed(p, M) ? 2 : 1) : s || h ? 2 : 0;
|
||||
p.state[j] = st;
|
||||
const q = cxy[j];
|
||||
if (!st || !q) continue;
|
||||
@@ -588,6 +590,7 @@ const tip = document.getElementById("tip");
|
||||
const STATE = (p, j) => {
|
||||
if (p.key === "globe") return p.state[j] ? "Station and signal in view" : "Neither in view";
|
||||
const S = lastS, s = inView(S.us, j), h = inView(S.m[p.key].ug, j);
|
||||
if (s && h && wrongSpeed(p, S.m[p.key])) return `Station and signal in view; the signal moves at ×${(S.m[p.key].vs / VM).toFixed(2)} the recorded speed, so its Doppler shift is wrong`;
|
||||
return s && h ? "Station and signal in view" : s ? "Station in view, no signal" : h ? "Signal, no station in view" : "Neither in view";
|
||||
};
|
||||
let lastS = null;
|
||||
|
||||
Reference in New Issue
Block a user