地球外文明のメッセージをエンコードおよびデコードします

こんにちはHabr。



この記事の動機は、実際、悲しい機会です。プエルトリコのアレシボ天文台の世界的に有名なラジオ望遠鏡は崩壊し、修理不可能です。長年にわたり、フルアパーチャ(直径304 m、最大10 GHzの周波数範囲)を備えた世界最大の無線望遠鏡であり、その助けを借りて多くの発見がなされました。ウィキペディアの写真では、まだ機能しています。





出典:en.wikipedia.org/wiki/Arecibo_Observatory



しかし、テキストは実際には別のイベントに関するものです。1974年、この望遠鏡から地球外文明へのメッセージが宇宙に送られました。何がどのようにエンコードされたか、詳細はカットの下にあります。



コーディング



まず、メッセージがどのように伝えられたかを理解するのは興味深いことです。ご存知のように、メッセージサイズはわずか1679ビット(約210バイト)で、2.38 GHzの周波数、450kWの電力で送信されました。送信には10ビット/秒の周波数変調を使用しました。番号1679は偶然に選択されたものではありません。これは2つの素数23と73の積であるため、画像を長方形の形に拡大する方法は1つしかありません。



WAV形式の既製のラジオメッセージは見つかりませんでしたが、バイナリ形式であり、Pythonを使用すると自分で簡単にサウンドを生成できます。エイリアンが聞くものを聞きたい人は、以下のコードをダウンロードして実行することができます。これにより、WAVファイルが生成されます。信頼性を高めるために、メッセージにもノイズが追加されています。



generate.py
import scipy.io.wavfile as wav
import scipy.signal as signal
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import os


message = """0000001010101000000000000101000001010000000100100010001000100
             1011001010101010101010100100100000000000000000000000000000000
             0000011000000000000000000011010000000000000000000110100000000
             0000000000101010000000000000000001111100000000000000000000000
             0000000001100001110001100001100010000000000000110010000110100
             0110001100001101011111011111011111011111000000000000000000000
             0000010000000000000000010000000000000000000000000000100000000
             0000000001111110000000000000111110000000000000000000000011000
             0110000111000110001000000010000000001000011010000110001110011
             0101111101111101111101111100000000000000000000000000100000011
             0000000001000000000001100000000000000010000011000000000011111
             1000001100000011111000000000011000000000000010000000010000000
             0100000100000011000000010000000110000110000001000000000011000
             1000011000000000000000110011000000000000011000100001100000000
             0110000110000001000000010000001000000001000001000000011000000
             0010001000000001100000000100010000000001000000010000010000000
             1000000010000000100000000000011000000000110000000011000000000
             1000111010110000000000010000000100000000000000100000111110000
             0000000010000101110100101101100000010011100100111111101110000
             1110000011011100000000010100000111011001000000101000001111110
             0100000010100000110000001000001101100000000000000000000000000
             0000000001110000010000000000000011101010001010101010100111000
             0000001010101000000000000000010100000000000000111110000000000
             0000001111111110000000000001110000000111000000000110000000000
             0110000000110100000000010110000011001100000001100110000100010
             1000001010001000010001001000100100010000000010001010001000000
             0000001000010000100000000000010000000001000000000000001001010
             00000000001111001111101001111000"""

def fftnoise(f):
    f = np.array(f, dtype='complex')
    n_p = (len(f) - 1) // 2
    phases = np.random.rand(n_p) * 2 * np.pi
    phases = np.cos(phases) + 1j * np.sin(phases)
    f[1:n_p+1] *= phases
    f[-1:-1-n_p:-1] = np.conj(f[1:n_p+1])
    return np.fft.ifft(f).real

def band_limited_noise(min_freq, max_freq, samples, samplerate=1):
    freqs = np.abs(np.fft.fftfreq(samples, 1/samplerate))
    f = np.zeros(samples)
    idx = np.where(np.logical_and(freqs>=min_freq, freqs<=max_freq))[0]
    f[idx] = 1
    return fftnoise(f)


message = ''.join(i for i in message if i.isdigit())
print("Original message:")
print(message)
print()

# Generate message
fs = 11025
f1, f2 = 3000, 4000
t_sym = 0.1
data = np.zeros(int(fs * t_sym * len(message)))
for p in range(len(message)):
    samples = np.linspace(0, t_sym, int(fs * t_sym), endpoint=False)
    freq = f2 if message[p] == '1' else f1
    data[int(fs * t_sym)*p:int(fs * t_sym)*(p + 1)] = 10000*(0.25*np.sin(2 * np.pi * freq * samples) + band_limited_noise(50, 5000, len(samples), fs))

wav.write('arecibo.wav', fs, np.int16(data))
print("WAV file saved")
      
      





聞き取りの便宜のために、周波数分離を増やしました。元のメッセージでは、わずか10Hzでした。残念ながら、habrではサウンドファイルの添付は許可されていません。希望する場合は、ファイルを自分で生成するか、一時リンクを使用できます



ちなみに、メッセージは1974年に送信されました。すぐそこ:





出典:en.wikipedia.org/wiki/Messier_13



すべての天文学愛好家によく知られており、小さな望遠鏡でも観察できるヘラクレス星座美しい星の群れM13。クラスターは22,000光年離れた場所にあるため、メッセージは長く続きます...



コーディングを理解しましたこのようなメッセージを受信したと想像してください。どのようにデコードできるか、見てみましょう。



デコード



周波数変調自体の原理は単純です-異なる周波数は0と1に対応します。スペクトル上では、次のようになります







。FSKをデコードするにはさまざまな方法があります。最も簡単な方法として、周波数の1つをフィルターで除外します。



fs, data = wav.read('arecibo.wav')

def butter_bandpass(lowcut, highcut, fs, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = signal.butter(order, [low, high], btype='band')
    return b, a

def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
    b, a = butter_bandpass(lowcut, highcut, fs, order=order)
    y = signal.lfilter(b, a, data)
    return y

f1, f2 = 3000, 4000
data_f2 = butter_bandpass_filter(data, f2 - 200, f2 + 200, fs, order=3)

plt.plot(data)
plt.plot(data_f2)
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.title("Signal")
plt.show()

      
      





結果は私たちに非常によく合っています:







もちろん、宇宙で22000年を経過した信号はわずかに弱くなる可能性がありますが、簡単にするために、エイリアンは中国のラジオではなく良いラジオを持っていると仮定します...



写真から1ビットの幅を簡単に判断できます。ビットを画像として出力する必要があります。なぜならメッセージは地球外の文明に送られました-定義上、「地上の」コーディングシステムを知らない人々-ラスター画像を送信することが唯一の論理的な決定でした。ヘラクレス星座では、ASCIIが何であるか、または神が禁じているUnicodeが何であるかを知らない可能性が高いですが、Galaxyのどこにでもラスターを画面に表示することは可能です。少なくともデジタル信号を受信できる文明は、それを表示するための何らかのモニターを持っている可能性があります。



画像のサイズはわかりませんが、1ビットのサイズはわかっており、メッセージ全体のサイズはわかっています。選択肢はそれほど多くないので、考えられるすべてのオプションを整理することができます。



ss = 1102  # Width of one symbol in samples
for iw in range(12*ss, 25*ss, ss):
    w, h = iw, 80
    image = Image.new('RGB', (w, h))

    px, py = 0, 0
    for p in range(data_f2.shape[0]):
        image.putpixel((px, py), (0, int(data_f2[p]//32), 0))
        px += 1
        if px >= w:
            px = 0
            py += 1
            if py >= h:
                break

    image = image.resize((w//10, 100*h))
    image.save("1/image-%d.png" % iw)
      
      







わかりやすくするために、画像を引き伸ばす必要がありました。これは、今日の基準では幅が23ピクセルであるため、控えめに言っても十分ではないためです。最終結果は非常にはっきりと見えます。







ファイナルカット:ウィキペディア







の画像とは異なり、元の画像はもちろんモノクロであり、信号に色分けはありません。 写真には多くのものがエンコードされています(もちろん、条件付きで)。たとえば、人の頭から2ピクセル上の幅の垂直線は、DNAスパイラルです(結局のところ、それは明らかですよね?)。残りのピクトグラムのデコードは、Wikipediaの上記のリンクにあります。







結論



ご覧のとおり、かなり多くの情報を210バイトにエンコードできます。一般に、深宇宙に信号を送信するタスクは単純ではありません。最も単純な変調方法しか期待できません。メッセージは宛先に届きますか?もちろん、おそらくありそうもない。このような「通信回線」のエネルギーと、信号を受信するために必要な受信機のおおよその感度が、送信時に評価されたかどうかはわかりません。はい、これは実際にはそれほど重要ではありません-そのような行動が誰かに宇宙を探検するように促した場合、それは無駄ではありませんでした。ええと、44000年で正確な答えを得ることができます、そして私は新しいデータが利用可能になったときにテキストを更新しようとします;)



All Articles