%matplotlib inline

# Importing standard Qiskit libraries
import random
from qiskit import *
from qiskit.tools.jupyter import *
from qiskit.visualization import *

#Get the library to check the answers
%pip install -I git+https://github.com/mnp-club/MnP_QC_Workshop.git
from mnp_qc_workshop_2020.bb84 import *

# Configuring account
provider = IBMQ.load_account()
backend = provider.get_backend('ibmq_qasm_simulator')  # with this simulator it wouldn't work \

# Initial setup
random.seed(64) # do not change this seed, otherwise you will get a different key

random.seed(64)

# This is your 'random' bit string that determines your bases
numqubits = 16
bob_bases = str('{0:016b}'.format(random.getrandbits(numqubits)))

def bb84():
    print('Bob\'s bases:', bob_bases)

    # Now Alice will send her bits one by one...
    all_qubit_circuits = []
    for qubit_index in range(numqubits):

        # This is Alice creating the qubit
        thisqubit_circuit = alice_prepare_qubit(qubit_index)

        # This is Bob finishing the protocol below
        bob_measure_qubit(bob_bases, qubit_index, thisqubit_circuit)
        
        # We collect all these circuits and put them in an array
        all_qubit_circuits.append(thisqubit_circuit)
        
    # Now execute all the circuits for each qubit
    results = execute(all_qubit_circuits, backend=backend, shots=1).result()
    # And combine the results
    bits = ''
    for qubit_index in range(numqubits):
        bits += [measurement for measurement in results.get_counts(qubit_index)][0]
    
    return bits

# Here is your task
def bob_measure_qubit(bob_bases, qubit_index, qubit_circuit):
    if bob_bases[qubit_index] == '1':
        qubit_circuit.h(0)
    qubit_circuit.measure(0, 0)

bits = bb84()      
print('Bob\'s bits: ', bits)
check_bits(bits)

alice_bases = '0100000101011100' # Alice's bases bits
key = ''

for i in range(16):
    if bob_bases[i] == alice_bases[i]:
        key += bits[i]

print(key)
check_key(key)

message = get_message()# encrypted message

decrypted = ''
for i in range(len(message)):
    x = key[-(i%len(key))-1]
    y = message[-i-1]
    if x == y:
        decrypted = '0' + decrypted
    else:
        decrypted = '1' + decrypted

print(decrypted)
check_decrypted(decrypted)

decrypted_to_string_ASCII = ''

i = 0
while i < 43:
    decrypted_to_string_ASCII += decrypted[]

check_message(decrypted_to_string_ASCII)