0

该函数的目标是改变 this 的元素

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

用编码(嵌套,消息)进入这个

>>>encode(image,'hello)
[[(14, 103, 255), (0, 3, 18)], [(22, 200, 0), (9, 9, 8)], [(0, 1, 0), (5, 122, 19)]]

消息中的每个字符都被转换成它对应的 ascii 事物,然后每个 ascii 事物被转换成 8 位,以 2 为基数的数字。得到了覆盖。

现在,要更改上面的列表,我所拥有的是:

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)

编码返回一个长度为 1200 的字符串,这是一个史诗般的失败,它看起来非常不友好。

请帮忙

4

1 回答 1

0

首先一些笔记

  • 如果使用位,请使用字符串作为最后的手段
  • 不要使用listorint作为变量名

最后,这并不是真正的编码,因为您永远无法取回原始数据。而不是这样做,异或密码可能更适合您的需求。

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)

这输出

> key: 0110100001100101011011000110110001101111
> [[(14, 103, 225), (0, 3, 18)], [(22, 200, 0), (9, 9, 8)], [(0, 1, 0), (5, 122, 19)]]

编辑:关于解码:如果我给了你编码列表和密钥,你怎么知道在编码过程之前这些位是什么?你不能。密钥只告诉您这些位被设置为什么,而不是在您设置它们之前它们是什么。

这就是为什么我建议使用 XOR 加密,而不是将位设置为特定值,我们翻转一些位并留下其他位。如果您没有密钥,您将不知道哪些位被翻转,哪些被留下。如果您确实有钥匙,请再次翻转它们以取回原件。

尝试更改这些行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
于 2013-10-04T03:29:23.723 回答