Skip to content

Instantly share code, notes, and snippets.

@njdart

njdart/Brief.md

Last active May 6, 2016
Embed
What would you like to do?
Image decoding for the #SETIDecryptChallenge

This brief is a copy of the #SETIDecryptChallenge challenge was taken from http://phl.upr.edu/library/notes/SETIChallenge:

Suppose a telescope on Earth receives a series of pulses from a fixed, unresolved source beyond the solar system. The source is a star about 50 light years from Earth. The pulses are in the form of short/long signals and they are received in a very narrow band around an electromagnetic frequency of 452.12919 MHz. A computer algorithm identifies the artificial nature of the pulses. It turns out the pulses carry a message. The pulses signify binary digits. Suppose further that you were, by whatsoever reason, put in charge of decoding this message.

Rules

  1. No restrictions on collaborations.
  2. Open discussion (social networks etc.) of possible solutions strongly encouraged.
  3. Three hints to the solutions can be offered as per request.
  4. Send your solutions to Dr. René Heller via e-mail (heller@mps.mpg.de), twitter (@DrReneHeller) or Facebook (DrReneHeller). Human-readable format and the format of the message are allowed.
  5. On 3 June 2016, a list of the successful SETI crackers (in chronological order) will be released.

Questions

  1. What is the typical body height of our interstellar counterparts?
  2. What is their typical lifetime?
  3. What is the scale of the devices they used to submit their message?
  4. Since when have they been communicating interstellar?
  5. What kind of object do they live on?
  6. How old is their stellar system?
from PIL import Image
# Guessed frame size
width = 359 # Initial set of 1's a prime number!
height = 757 # Initial set of 000..001's also a prime number!
frameCount = 7 # len(message) / (width*height) == 7
framesWithHeaders = [3, 4, 5, 6] # frames 3 and above seem to have information at the top of them
C = 299792458 # Speed of light
def chunker(list, size):
for i in range(0, len(list), size):
yield list[i: i+size]
def frame3headerDecoder(row1Positive, row1Negative, row2Positive, row2Negative):
print('frame 3 row 1 positive length {}'.format(len(row1Positive)))
print('frame 3 row 1 negative length {}'.format(len(row1Negative)))
print('frame 3 row 2 positive length {}'.format(len(row2Positive)))
print('frame 3 row 2 negative length {}'.format(len(row2Negative)))
# print([i for i in chunker(row1Positive, 13)])
# print([i for i in chunker(row1Negative, 13)])
# print([i for i in chunker(row2Positive, 13)])
# print([i for i in chunker(row2Negative, 13)])
messageFrequency = 452129190
messagePeriod = 1/messageFrequency
messageWavelength = C/messageFrequency
print('Received Message Frequency: ' + str(messageFrequency))
print('Received Message Period: ' + str(messagePeriod))
print('Received Message Wavelength: ' + str(messageWavelength))
print()
print('Xor')
xorPositive = ['1' if int(a) ^ int(b) else '0' for a,b in zip(row1Positive, row2Positive)]
print(int(''.join(xorPositive), 2))
xorNegative = ['1' if int(a) ^ int(b) else '0' for a,b in zip(row1Positive[::-1], row2Positive[::-1])]
print(int(''.join(xorNegative), 2))
row1PositiveInt = int(row1Positive, 2)
row1NegativeInt = int(row1Negative, 2)
row2PositiveInt = int(row2Positive, 2)
row2NegativeInt = int(row2Negative, 2)
print()
print('Interpreted as Int')
print(row1PositiveInt)
print(row2PositiveInt)
print(row1NegativeInt)
print(row2NegativeInt)
print()
print('Interpreted as fraction')
print(row1PositiveInt / row2PositiveInt)
print(row2PositiveInt / row1PositiveInt)
print(row1NegativeInt / row2NegativeInt)
print(row2NegativeInt / row1NegativeInt)
print()
print('Interpreted as fraction (read backwards)')
print(int(row1Positive[::-1]) / int(row2Positive[::-1]))
print(int(row2Positive[::-1]) / int(row1Positive[::-1]))
print(int(row1Negative[::-1]) / int(row2Negative[::-1]))
print(int(row2Negative[::-1]) / int(row1Negative[::-1]))
"""
Assuming This V is the value given
OurFrequency = (Oscilations / TheirSITime)
TheirSITime = oscilations / OurFrequency
"""
print()
print('Guessing alient SI time assumning frequency')
print(row1PositiveInt / messageFrequency)
print(row1NegativeInt / messageFrequency)
print(row2PositiveInt / messageFrequency)
print(row2NegativeInt / messageFrequency)
print()
print('Guessing alient SI time assumning frequency (Read Backwards)')
print(int(row1Positive[::-1], 2) / messageFrequency)
print(int(row1Negative[::-1], 2) / messageFrequency)
print(int(row2Positive[::-1], 2) / messageFrequency)
print(int(row2Negative[::-1], 2) / messageFrequency)
def frame4headerDecoder(row1Positive, row1Negative, row2Positive, row2Negative):
# print('frame 4 row 1 positive length {}'.format(len(row1Positive.strip('0'))))
# print('frame 4 row 1 negative length {}'.format(len(row1Negative.strip('1'))))
# print('frame 4 row 2 positive length {}'.format(len(row2Positive.strip('0'))))
# print('frame 4 row 2 negative length {}'.format(len(row2Negative.strip('1'))))
pass
def frame5headerDecoder(row1Positive, row1Negative, row2Positive, row2Negative):
# print('frame 5 row 1 positive length {}'.format(len(row1Positive.strip('0'))))
# print('frame 5 row 1 negative length {}'.format(len(row1Negative.strip('1'))))
# print('frame 5 row 2 positive length {}'.format(len(row2Positive.strip('0'))))
# print('frame 5 row 2 negative length {}'.format(len(row2Negative.strip('1'))))
pass
def frame6headerDecoder(row1Positive, row1Negative, row2Positive, row2Negative):
# print('frame 6 row 1 positive length {}'.format(len(row1Positive.strip('0'))))
# print('frame 6 row 1 negative length {}'.format(len(row1Negative.strip('1'))))
# print('frame 6 row 2 positive length {}'.format(len(row2Positive.strip('0'))))
# print('frame 6 row 2 negative length {}'.format(len(row2Negative.strip('1'))))
pass
with open('/home/nic/Downloads/SETI_message.txt', 'r') as file:
message = file.read()
for frame in range(frameCount):
positiveHeader = ['', '']
negativeHeader = ['', '']
negativeImage = Image.new('1', (width, height))
negativeCanvas = negativeImage.load()
posativeImage = Image.new('1', (width, height))
posativeCanvas = posativeImage.load()
frameContainsHeader = frame in framesWithHeaders
if frameContainsHeader:
negativeHeaderImage = Image.new('1', (width, 2))
negativeHeaderCanvas = negativeHeaderImage.load()
positiveHeaderImage = Image.new('1', (width, 2))
positiveHeaderCanvas = positiveHeaderImage.load()
for x in range(width):
for y in range(height):
value = message[x + width * (y + frame * height)]
posativeCanvas[x, y] = 1 if value == '1' else 0
negativeCanvas[x, y] = 1 if value == '0' else 0
if frameContainsHeader and y < 2:
negativeHeaderCanvas[x, y] = 1 if value == '1' else 0
positiveHeaderCanvas[x, y] = 1 if value == '0' else 0
positiveHeader[y] += value
negativeHeader[y] += '1' if value == '0' else '0'
negativeImage.save('/tmp/SETI_message_frame_{}_negative.png'.format(frame))
posativeImage.save('/tmp/SETI_message_frame_{}_positive.png'.format(frame))
if frameContainsHeader:
negativeHeaderImage.save('/tmp/SETI_message_frame_{}_header_negative.png'.format(frame))
positiveHeaderImage.save('/tmp/SETI_message_frame_{}_header_positive.png'.format(frame))
# A lovely hack to call the decoder methods
{
3: frame3headerDecoder,
4: frame4headerDecoder,
5: frame5headerDecoder,
6: frame6headerDecoder
# }[frame](positiveHeader[0], negativeHeader[0], positiveHeader[1], negativeHeader[1])
}[frame](positiveHeader[0].strip('0')[1:-1], negativeHeader[0].strip('1')[1:-1], positiveHeader[1].strip('0')[1:-1], negativeHeader[1].strip('1')[1:-1])
# Assuming asyncronous transmission style formatting with a start and stop bit
# Frame 0 appears to be a calibration frame
# Frame 1 appears to be incremeting binary when read from left-to-right
# Frame 2 appears to be increasing prime numbers in binary
# Frame 3 appears to be a waveform, presumably of frequency used to transmit the message (452129190 Hz).
View raw

(Sorry about that, but we can’t show files that are this big right now.)

This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment