Last active
September 20, 2019 15:43
-
-
Save rgov/da5963b1e74469e9bf9bb7fd090bdf01 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
import random | |
import sys | |
import time | |
nsymbols = int(sys.argv[1]) if len(sys.argv) == 2 else 26 | |
nbits_per_symbol = math.ceil(math.log(nsymbols, 2)) | |
ntotal_values = 2**nbits_per_symbol | |
ninvalid_values = ntotal_values - nsymbols | |
if ninvalid_values == 0: | |
print('Cannot send any subliminal bits when # of symbols is a power of two') | |
sys.exit(0) | |
def encode(symbol, extra_bit): | |
extra_used = False | |
if symbol < ninvalid_values: | |
if extra_bit == 1: | |
symbol += nsymbols | |
extra_used = True | |
return symbol, extra_used | |
def decode(symbol): | |
extra_bit = None | |
if symbol >= nsymbols: | |
symbol -= nsymbols | |
extra_bit = 1 | |
elif symbol < ninvalid_values: | |
extra_bit = 0 | |
return symbol, extra_bit | |
subliminal = 'Hello world!' | |
sub_bits = [] | |
for c in subliminal: | |
sub_bits.extend((int(b) for b in bin(ord(c))[2:].rjust(8, '0'))) | |
recv_sub_bits = [] | |
sent_sum = recv_sum = 0 | |
sent_count = sent_extra = 0 | |
while sub_bits: | |
symbol = random.randrange(nsymbols) | |
encoded, extra_used = encode(symbol, sub_bits[0]) | |
sent_sum += symbol | |
sent_count += 1 | |
if extra_used: | |
sub_bits.pop(0) | |
sent_extra += 1 | |
decoded, extra_bit = decode(encoded) | |
recv_sum += decoded | |
if extra_bit is not None: | |
recv_sub_bits.append(extra_bit) | |
print('Sent sum:', sent_sum) | |
print('Recv sum:', recv_sum) | |
if sent_extra > 0: | |
print('Subliminal bit per %.3f symbols' % (sent_count / sent_extra)) | |
else: | |
print('No subliminal bits sent yet') | |
recv_sub = '' | |
for i in range(0, len(recv_sub_bits), 8): | |
if i + 7 >= len(recv_sub_bits): | |
break | |
b = 0 | |
for j in range(8): | |
b = (b << 1) | recv_sub_bits[i + j] | |
recv_sub += chr(b) | |
print('Subliminal message:', recv_sub) | |
print('\033[4A', end='') | |
time.sleep(0.02) | |
print() | |
print() | |
print() | |
print() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment