spacebook: original code
This commit is contained in:
parent
cb7a567f44
commit
a63a569a54
|
@ -19,63 +19,44 @@ We're given a boresight vector $\vec{v}\in\mathbb{R}^3$ for each star, and a mag
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
*Note that code from here on in this report is reconstructed, since I accidentally overwrote the original copy. I took the chance to use scipy for Kabsch this time instead of the original package I used, [`rmsd`](https://github.com/charnley/rmsd).*
|
|
||||||
|
|
||||||
My immediate suspicion was that we could take the outliers (simply by thresholding for stars with $m>500$) and, for each, directly match it to the catalog by finding the star with closest magnitude in the catalog:
|
My immediate suspicion was that we could take the outliers (simply by thresholding for stars with $m>500$) and, for each, directly match it to the catalog by finding the star with closest magnitude in the catalog:
|
||||||
|
|
||||||
```{.python}
|
```{.python}
|
||||||
def match_brightest_stars(unknown, catalog):
|
refstars_magsorted = sorted(refstars, key=lambda x:x['m'])[::-1]
|
||||||
brightest = []
|
|
||||||
catalog_matches = []
|
|
||||||
for star in unknown:
|
|
||||||
if star['m'] < 500:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# find closest magnitude in catalog
|
catalog_magnitudes = np.array([x['m'] for x in catalog])
|
||||||
match = np.argmin(np.abs(np.array([s['m'] for s in catalog]) - star['m']))
|
matches = []
|
||||||
print(f'[+] matched {star} to {catalog[match]}')
|
|
||||||
brightest.append(star)
|
|
||||||
catalog_matches.append(catalog[match])
|
|
||||||
|
|
||||||
return brightest, catalog_matches
|
for idx, star in enumerate(refstars_magsorted):
|
||||||
|
if star['m'] <= 500:
|
||||||
|
break
|
||||||
|
match = np.argmin(np.abs(catalog_magnitudes-star['m']))
|
||||||
|
matches.append(match)
|
||||||
```
|
```
|
||||||
|
|
||||||
We can then align those brightest stars to their closest magnitude matches using the Kabsch algorithm:
|
We can then align those brightest stars to their closest magnitude matches using the Kabsch algorithm:
|
||||||
```{.python}
|
```{.python}
|
||||||
def orient(ref, catalog):
|
P = np.vstack([x['v'] for x in [catalog[i] for i in matches]])
|
||||||
P = [s['v'] for s in catalog]
|
Q = np.vstack([x['v'] for x in refstars_magsorted[:4]])
|
||||||
Q = [s['v'] for s in ref]
|
print("rmsd: {}".format(calculate_rmsd.kabsch_rmsd(P,Q)))
|
||||||
|
rotation_mtx = calculate_rmsd.kabsch(P, Q)
|
||||||
rot, rmsd = Rotation.align_vectors(P, Q)
|
rotation = Rotation.from_matrix(rotation_mtx)
|
||||||
print(f'[+] aligned; rmsd = {rmsd}')
|
|
||||||
return rot
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then for each unknown star with vector $\vec{v}$, we can find its catalog index by evaluating
|
Knowing the rotation, we can rotate all stars into the catalog reference frame and then evaluate
|
||||||
$$\arg\min_{\vec{u}\in\text{catalog}} \norm{\vec{u}-\vec{v}}_2$$
|
$$\arg\min_{\vec{u}\in\text{catalog}} \norm{\vec{u}-\vec{v}}_2$$
|
||||||
for every challenge:
|
for each unknown star with vector $\vec{v}$ to find the closest star in the dictionary:
|
||||||
```{.python}
|
```{.python}
|
||||||
for _ in range(5):
|
rotated = [dict(v=rotation.apply(x['v']), m=x['m']) for x in refstars_magsorted]
|
||||||
unknown_stars = read_starfile(r.recvuntil('\n\n').decode())
|
found_idxes = []
|
||||||
|
for star in rotated:
|
||||||
# find pairs
|
found_idxes.append(np.argmin([np.linalg.norm(star['v']-catalogstar['v']) for catalogstar in catalog]))
|
||||||
unknown_ref, catalog_ref = match_brightest_stars(unknown_stars, catalog)
|
|
||||||
# get attitude
|
|
||||||
attitude = orient(unknown_ref, catalog_ref)
|
|
||||||
# rotate each star to catalog-referenced coordinates and match by L2 norm
|
|
||||||
index_guesses = []
|
|
||||||
for star in unknown_stars:
|
|
||||||
v = attitude.apply(star['v'])
|
|
||||||
index_guesses.append(np.argmin([np.linalg.norm(catalog_star['v'] - v)
|
|
||||||
for catalog_star in catalog]))
|
|
||||||
|
|
||||||
r.send(','.join(map(str, index_guesses))+'\n')
|
|
||||||
r.recvuntil('Left...\n')
|
|
||||||
print(r.clean())
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It's then trivial to send `found_idxs` back to the challenge as a comma-separated string of indices for each problem sent to us; the server happily sends us the flag after we answer its questions.
|
||||||
|
|
||||||
### Full code
|
### Full code
|
||||||
```{.python include=spacebook.py}
|
```{.python include=spacebook-original.py}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import numpy as np
|
||||||
|
from pwnlib import tubes
|
||||||
|
import time
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from rmsd import calculate_rmsd
|
||||||
|
from scipy.spatial.transform import Rotation
|
||||||
|
%matplotlib inline
|
||||||
|
|
||||||
|
def read_starfile(data):
|
||||||
|
stars = []
|
||||||
|
for line in data.strip().split('\n'):
|
||||||
|
[x,y,z,m] = [float(s.strip()) for s in line.split(',')]
|
||||||
|
stars.append({'v': np.array([x,y,z]), 'm':m})
|
||||||
|
return stars
|
||||||
|
|
||||||
|
with open('./spacebook-golf56788echo/test.txt') as f:
|
||||||
|
catalog = read_starfile(f.read())
|
||||||
|
|
||||||
|
TICKET = 'THE_TICKET'
|
||||||
|
r = tubes.remote.remote('spacebook.satellitesabove.me', 5015)
|
||||||
|
r.send(TICKET+'\n')
|
||||||
|
time.sleep(0.5)
|
||||||
|
r.recvuntil('Ticket please:\n', drop=True)
|
||||||
|
|
||||||
|
for _ in range(5):
|
||||||
|
refstars = read_starfile(r.recvuntil('\n\n').decode())
|
||||||
|
|
||||||
|
refstars_magsorted = sorted(refstars, key=lambda x:x['m'])[::-1]
|
||||||
|
|
||||||
|
catalog_magnitudes = np.array([x['m'] for x in catalog])
|
||||||
|
matches = []
|
||||||
|
|
||||||
|
for idx, star in enumerate(refstars_magsorted):
|
||||||
|
if star['m'] <= 500:
|
||||||
|
break
|
||||||
|
match = np.argmin(np.abs(catalog_magnitudes-star['m']))
|
||||||
|
matches.append(match)
|
||||||
|
print(matches)
|
||||||
|
|
||||||
|
P = np.vstack([x['v'] for x in [catalog[i] for i in matches]])
|
||||||
|
Q = np.vstack([x['v'] for x in refstars_magsorted[:4]])
|
||||||
|
print("rmsd: {}".format(calculate_rmsd.kabsch_rmsd(P,Q)))
|
||||||
|
rotation_mtx = calculate_rmsd.kabsch(P, Q)
|
||||||
|
rotation = Rotation.from_matrix(rotation_mtx)
|
||||||
|
|
||||||
|
rotated = [dict(v=rotation.apply(x['v']), m=x['m']) for x in refstars_magsorted]
|
||||||
|
found_idxes = []
|
||||||
|
for star in rotated:
|
||||||
|
found_idxes.append(np.argmin([np.linalg.norm(star['v']-catalogstar['v']) for catalogstar in catalog]))
|
||||||
|
|
||||||
|
r.send(','.join([str(x) for x in found_idxes]) + '\n')
|
||||||
|
time.sleep(0.1)
|
||||||
|
r.recvuntil('Left...\n')
|
||||||
|
print(r.clean())
|
Loading…
Reference in New Issue