import os, hashlib, binascii

# Ustalanie wartości ziarna
nonce = b'3e08816f1377' # Pierwsze 6 bajtów z wiadomości w książce
hexnonce = binascii.hexlify(nonce)
oursecret = 61983 # Klucz z książki
concatenated_hex = hexnonce + format(oursecret, 'x').encode()
even_length = concatenated_hex.rjust(len(concatenated_hex) + len(concatenated_hex) % 2, b'0')
hexhash = hashlib.sha256(binascii.unhexlify(even_length)).hexdigest()
newseed = (int(hexhash, 16)) % 2**32
print("Ziarno: ", newseed)

#Szyfrowanie wiadomości 
def crand(seed):
    r=[]
    r.append(seed)
    for i in range(30):
        r.append((16807*r[-1]) % 2147483647)
        if r[-1] < 0:
            r[-1] += 2147483647
    for i in range(31, 34):
        r.append(r[len(r)-31])
    for i in range(34, 344):
        r.append((r[len(r)-31] + r[len(r)-3]) % 2**32)
    while True:
        next = r[len(r)-31]+r[len(r)-3] % 2**32
        r.append(next)
        yield (next >> 1 if next < 2**32 else (next % 2**32) >> 1)

mygen = crand(newseed)
rands = [next(mygen) for i in range(4)]
plaintext = b"To jest wiadomosc."
hexplain = binascii.hexlify(plaintext)
hexkey = "".join(map(lambda x: format(x, 'x')[-6:], rands))
cipher_as_int = int(hexplain, 16) ^ int(hexkey, 16)
cipher_as_hex = format(cipher_as_int, 'x')

print("Wartość jednorazowa: ", nonce)
print("Szyfrogram: ", cipher_as_hex)

#Odszyfrowywanie
ciphertext = b'546f206a6573a3e033cf84f4c1bec3e04b64' # Pozostałe bajty z wiadomości w książce
hexkey = "".join(map(lambda x: format(x, 'x')[-6:], rands))
plain_as_int = int(ciphertext, 16) ^ int(hexkey, 16)
plain_as_hex = format(plain_as_int, 'x')
plaintext = binascii.unhexlify(plain_as_hex)

print("Odszyfrowana wiadomość: ", plaintext)

