Python 如何根据其他两个不同列表和函数的元素更改嵌套列表中的值很难理解

Python 如何根据其他两个不同列表和函数的元素更改嵌套列表中的值很难理解,python,list,python-2.7,tuples,nested-lists,Python,List,Python 2.7,Tuples,Nested Lists,该功能的目标是更改此功能的元素 image=[[(15,103,225), (0,3,19)], [(22,200,1), (8,8,8)], [(0,0,0), (5,123,19)]] 使用encode(嵌套,消息)将其转换为 消息中的每个字符都被转换为相应的ascii内容,然后每个ascii内容都被转换为8位数字,以两个数字为基数。我把它盖好了 现在,要更改上面的列表,我要做的是: def char_to

该功能的目标是更改此功能的元素

image=[[(15,103,225), (0,3,19)],               
      [(22,200,1), (8,8,8)],               
      [(0,0,0), (5,123,19)]]
使用encode(嵌套,消息)将其转换为

消息中的每个字符都被转换为相应的ascii内容,然后每个ascii内容都被转换为8位数字,以两个数字为基数。我把它盖好了

现在,要更改上面的列表,我要做的是:

def char_to_bits(char):
"""char_to_bits(char) -> string

Convert the input ASCII character to an 8 bit string of 1s and 0s.

>>> char_to_bits('A')
'01000001'
"""
result = ''
char_num = ord(char)
for index in range(8):
    result = get_bit(char_num, index) + result
return result


def get_bit(int, position):
"""get_bit(int, position) -> bit

Return the bit (as a character, '1' or '0') from a given position
in a given integer (interpreted in base 2).

The least significant bit is at position 0. The second-least significant
bit is at position 1, and so forth.

>>> for pos in range(8):
...     print(b.get_bit(167, pos))
... 
1
1
1
0
0
1
0
1
"""
if int & (1 << position):
    return '1'
else:
    return '0'

def message_to_bits(message): 
if len(message)==0:
    return ''                                                           
for m in message:
    return "".join("".join(str(bits.char_to_bits(m)))for m in message) 

def set_bit_on(int, position):
"""set_bit_on(int, position) -> int

Set the bit at a given position in a given integer to 1,
regardless of its previous value, and return the new integer
as the result.

The least significant bit is at position 0. The second-least significant
bit is at position 1, and so forth.

>>> set_bit_on(0, 0)
1
>>> set_bit_on(0, 1)
2
>>> set_bit_on(167, 3)
175
"""
    return int | (1 << position)

def set_bit_off(int, position):
"""set_bit_off(int, position) -> int

Set the bit at a given position in a given integer to 0,
regardless of its previous value, and return the new integer
as the result.

The least significant bit is at position 0. The second-least significant
bit is at position 1, and so forth.

>>> set_bit_off(0, 0)
0
>>> set_bit_off(1, 0)
0
>>> set_bit_off(167, 0)
166
>>> set_bit_off(175, 3)
167
"""
    return int & ~(1 << position)

def set_bit(int, bit, position):
"""set_bit(int, bit, position) -> int

Set the bit at a given position to the given bit (as a char, either
'1' or '0') regardless of its previous value, and return the new integer
as the result.

The least significant bit is at position 0. The second-least significant
bit is at position 1, and so forth.

>>> set_bit(0, '1', 0)
1
>>> set_bit(0, '1', 1)
2
>>> set_bit(0, '1', 2)
4
>>> set_bit(0, '1', 3)
8
>>> set_bit(175, '0', 3)
167
>>> set_bit(175, '1', 3)
175
"""

    if bit == '1':
        return set_bit_on(int, position)
    else:
        return set_bit_off(int, position)​

from collections import Iterable
def flatten(nested):      
    for item in nested:          
        if isinstance(item, Iterable) and not isinstance(item, basestring):             
            for x in flatten(item):                  
                yield x
        else:
            yield item
def encode(nested, message):
    position= 0
    fnested= list(flatten(nested))
    bitlist= list("".join("".join(str(bits.char_to_bits(m)))for m in message))
    for int in fnested:
        for bit in bitlist:
            return "".join("".join(("".join(str(bits.set_bit(int,bit,position)))for int in fnested)) for bit in bitlist)
def char_到_位(char):
“”“char\u到_位(char)->字符串
将输入的ASCII字符转换为1和0的8位字符串。
>>>字符到字节('A')
'01000001'
"""
结果=“”
char_num=ord(char)
对于范围(8)中的索引:
结果=获取位(字符数,索引)+结果
返回结果
def get_位(整数,位置):
“”“获取位(int,position)->位
从给定位置返回位(作为字符“1”或“0”)
在给定整数中(以基数2解释)。
最低有效位位于位置0。第二个最低有效位
位位于位置1,依此类推。
>>>对于范围(8)内的位置:
…打印(b.get_位(167,位置))
... 
1.
1.
1.
0
0
1.
0
1.
"""
如果int&(1先做一些注释

  • 如果使用位,请使用字符串作为最后手段
  • 不要使用
    list
    int
    作为变量名
最后,这并不是一种真正的编码,因为您永远无法恢复原始数据。 与此相反,XOR密码可能更适合您的需要

def message_to_bits(msg):
    result = 0
    for c in msg:
        result = (result << 8) | ord(c)
    return result

def get_bit(num, position):
    return num & (1 << position)

def set_bit_on(num, position):
    return num | (1 << position)

def set_bit_off(num, position):
    return num & ~(1 << position)

def set_bit(num, value, position):
    if value:
        return num | (1 << position)
    else:
        return num & ~(1 << position)

def encode(nested_list_thing, key):
    key_bits = message_to_bits(key)
    key_length = 8 * len(key)
    print ('key: {:0%db}' % key_length).format(key_bits)

    # Mask keeps track of which bit in
    # key_bits we are using to set the value of
    mask = 1 << (key_length - 1)

    result = []
    for list_ in nested_list_thing:
        encoded_list = []

        for tuple_ in list_:
            encoded_tuple = []

            for num in tuple_:
                # Encode the number
                set_to_bit = key_bits & mask
                encoded_num = set_bit(num, set_to_bit, 0)
                encoded_tuple.append(encoded_num)
                # Move to next position in key_bits
                mask = mask >> 1
            encoded_list.append(tuple(encoded_tuple))
        result.append(encoded_list)
    return result

image = [[(15, 103, 225), (0, 3, 19)],
        [(22, 200, 1), (8, 8, 8)],
        [(0, 0, 0), (5, 123, 19)]]
key = 'hello'
print encode(image, key)
编辑: 关于解码: 如果我给了你编码列表和密钥,你怎么知道在编码过程之前比特是什么?你不能。密钥只告诉你比特被设置成什么,而不是你设置它们之前比特是什么

这就是为什么我建议使用异或加密,而不是将位设置为特定值,我们翻转一些位,让其他位单独使用。如果您没有密钥,您不知道哪些位被翻转,哪些位被保留。如果您确实有密钥,您可以再次翻转它们以获取原始值

尝试在
encode

    ...
        for num in tuple_:
            xor_key = 1 if key_bits & mask else 0
            encoded_num = num ^ xor_key
            encoded_tuple.append(encoded_num)
            # Move to next position in key_bits
            mask = mask >> 1
    ...
然后这个在底部

image = [[(15, 103, 225), (0, 3, 19)],
        [(22, 200, 1), (8, 8, 8)],
        [(0, 0, 0), (5, 123, 19)]]

key = 'hello'

encoded_image = encode(image, key)
decoded_image = encode(encoded_image, key)

print encoded_image
print decoded_image
它应该给你

> [[(15, 102, 224), (0, 2, 19)], [(22, 200, 1), (9, 9, 8)], [(0, 1, 0), (4, 123, 18)]] # <-- encoded
> [[(15, 103, 225), (0, 3, 19)], [(22, 200, 1), (8, 8, 8)], [(0, 0, 0), (5, 123, 19)]]  # <-- decoded

[(15,102,224),(0,2,19)],[(22,200,1),(9,9,8)],[(0,1,0),(4,123,18)]。[(15,103,225),(0,3,19)],[(22,200,1),(8,8,8)],[(0,0,0),(5,123,19)]你能解释一下这些数字是如何变化的吗?我不明白为什么
(14,103,255)
被保留了,但
(0,3,19)变成了
。函数消息\u to \u位将消息('hello')更改为二进制。这些二进制内容是函数set\u位中的位,并进行编码。“hello”的二进制是'0110101011000110011011111'。位置始终是0。int是图像中的元素。因此set\u位(15,'0',0)返回14。set\u位(19,'0',0)返回18。整数转换为8位二进制,最后一位转换为位,新的8位二进制转换为基数10并返回。元组的第一个元素具有消息二进制的第一位的位。元组中的第二位,二进制中的第二位,等等。如何使其仅打印新的嵌套列表?没有键?你什么意思?不能得到原始数据?因为,我需要做另一个函数,输入新的元组,它会返回二进制内容。唯一可以改变的函数是消息位,扁平化和编码,因为任务要求我使用其他的。抱歉问得太多。你可以去掉在
encode
中打印语句以避免打印密钥。至于解码,我将用信息更新帖子。>>>编码(图像,'hello')[[(225,),(18,)],[(0,),(8,),[(1,),(19,)]]我在运行xor时得到了这个消息。抱歉,粘贴时缩进被弄乱了。我现在已经修复了它。
image = [[(15, 103, 225), (0, 3, 19)],
        [(22, 200, 1), (8, 8, 8)],
        [(0, 0, 0), (5, 123, 19)]]

key = 'hello'

encoded_image = encode(image, key)
decoded_image = encode(encoded_image, key)

print encoded_image
print decoded_image
> [[(15, 102, 224), (0, 2, 19)], [(22, 200, 1), (9, 9, 8)], [(0, 1, 0), (4, 123, 18)]] # <-- encoded
> [[(15, 103, 225), (0, 3, 19)], [(22, 200, 1), (8, 8, 8)], [(0, 0, 0), (5, 123, 19)]]  # <-- decoded