Как сравнить элементы в двух списках и создать новый список из результатов? - PullRequest
1 голос
/ 22 января 2020

В качестве упражнения я пытаюсь написать простой XOR-расшифровщик.

Я хочу взять двоичный вход ASCII и сохранить его в списке. Затем возьмите двоичный ключ и сохраните его в списке.

Функция должна сравнивать элементы из обоих списков соответственно и проверять, являются ли два сравниваемых элемента 0 или 1. Если оба равны 0 или оба равны 1, то выходной элемент = 0. Если один элемент равен 0 и другой 1 или наоборот, затем выходной элемент = 1.

Для каждого сравнения, которое выполняет функция, она должна сохранять выходной двоичный элемент в списке result. Как только функция выполняет итерацию по каждому элементу в обоих списках, она должна вывести итоговый двоичный вывод result.

Мой лог c:

def xor():

    binary_plaintext = [1,0,1,0,1,0,0,1, 0,1,0,0,0,1,1,0, 1,1,1,0,0,0,0,1]
    binary_key =       [1,1,1,1,1,0,1,1, 0,0,0,0,1,1,1,1, 1,0,1,1,0,1,0,1]
    result =           []

    for plaintext_item in binary_plaintext and key_item in binary_key:

        if plaintext_item == 1 and key_item == 1: # XOR 1|1 = 0
            output = 0
            output.append(result)

        elif plaintext_item == 0 and key_item == 0: # XOR 0|0 = 0
            output = 0
            output.append(result)

        elif plaintext_item == 1 and key_item == 0: # XOR 1|0 = 1
            output = 1
            output.append(result)

        elif plaintext_item == 0 and key_item == 1: # XOR 0|1 = 1
            output = 1
            output.append(result)

        print(result)

xor()

Мой пример не работает , Каков будет правильный способ сравнения списков binary_plaintext и списка binary_key и итерации их элементов, чтобы выходное значение могло быть сохранено в новом списке?

Ответы [ 8 ]

2 голосов
/ 22 января 2020

По сути, вы можете реализовать XOR с добавлением обоих входов, а затем по модулю 2.

Например, это будет работать:

result = [(x+y) % 2 for x,y in zip(binary_plaintext,binary_key)]

print(result)

Выход

[0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0]
1 голос
/ 22 января 2020

Для справки вы можете сделать это с помощью numpy.

import numpy as np

x = np.asarray([0,0,1,1])
y = np.asarray([0,1,0,1])

xor = x ^ y

. В вашей собственной реализации используйте zip, чтобы получить совпадающие пары из двух списков. Вы также поменяли вывод и результаты по ошибке:

def xor():

    binary_plaintext = [1,0,1,0,1,0,0,1, 0,1,0,0,0,1,1,0, 1,1,1,0,0,0,0,1]
    binary_key =       [1,1,1,1,1,0,1,1, 0,0,0,0,1,1,1,1, 1,0,1,1,0,1,0,1]
    result =           []

    for plaintext_item, key_item in zip(binary_plaintext, binary_key):

        if plaintext_item == 1 and key_item == 1: # XOR 1|1 = 0
            output = 0
            result.append(output)

        elif plaintext_item == 0 and key_item == 0: # XOR 0|0 = 0
            output = 0
            result.append(output)

        elif plaintext_item == 1 and key_item == 0: # XOR 1|0 = 1
            output = 1
            result.append(output)

        elif plaintext_item == 0 and key_item == 1: # XOR 0|1 = 1
            output = 1
            result.append(output)

    print(result)

xor()
1 голос
/ 22 января 2020

Пара ошибок в вашей функции - во-первых, чтобы перебирать списки параллельно, вы можете использовать zip() - чтобы мы могли заменить

for plaintext_item in binary_plaintext and key_item in binary_key:

на

for plaintext_item, key_item in zip(binary_plaintext, binary_key):

Во-вторых, вам нужно использовать

result.append(output)

вместо

output.append(result)

И, наконец, не использовать отступ print(result), чтобы извлечь его из для l oop.

Исправленная функция затем печатает

[0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0]
1 голос
/ 22 января 2020

Это должно помочь:


result = [int(binary_plaintext[entry]!=binary_key[entry]) for entry in range(len(binary_plaintext))]
# [0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0]
1 голос
/ 22 января 2020

Вы никогда не измените result, хотя вы неоднократно добавляете его к output, когда я думаю, что у вас есть это в обратном направлении (то есть добавьте output к result).

0 голосов
/ 22 января 2020

это должно работать, отредактировал ваш код для правильного результата

def xor():

    binary_plaintext = [1,0,1,0,1,0,0,1, 0,1,0,0,0,1,1,0, 1,1,1,0,0,0,0,1]
    binary_key =       [1,1,1,1,1,0,1,1, 0,0,0,0,1,1,1,1, 1,0,1,1,0,1,0,1]
    result =           []

    for i in range(0,len(binary_plaintext)):

        if binary_plaintext[i] == binary_key[i]: # XOR 1|1 = 0 # XOR 0|0 = 0
            output = 0
            result.append(output)

        elif binary_plaintext[i] == 1 and binary_key[i] == 0: # XOR 1|0 = 1
            output = 1
            result.append(output)

        elif binary_plaintext[i] == 0 and binary_key[i] == 1: # XOR 0|1 = 1
            output = 1
            result.append(output)

    print(result)

xor()
0 голосов
/ 22 января 2020

Вы можете использовать почтовый индекс. Я использую python3.

for text,key in  zip(binary_plaintext, binary_key)
   result.append(text ^ key)
0 голосов
/ 22 января 2020

Мы можем использовать оператор python ^, чтобы сделать это довольно просто:

def xor():
    binary_plaintext = [1,0,1,0,1,0,0,1, 0,1,0,0,0,1,1,0, 1,1,1,0,0,0,0,1]
    binary_key =       [1,1,1,1,1,0,1,1, 0,0,0,0,1,1,1,1, 1,0,1,1,0,1,0,1]
    return [a ^ b for (a, b) in zip(binary_plaintext, binary_key]

Мы сжимаем вместе binary_plaintext и binary_key и XOR содержимое каждого кортежа в понимании списка.

Предполагается, что binary_plaintext и binary_key имеют одинаковую длину.

...