Стенография Python слишком много значений, чтобы распаковать ошибку - PullRequest
0 голосов
/ 27 августа 2018

Я получаю ошибку too many values to unpack (expected 3). Когда я добавляю [], если это сам кортеж, я получаю ошибку not enough values to unpack (expected 3, got 1) Ошибка возрастает в строке 50, r, g, b = hex2rgb(newpix)

Я собираюсь поделиться всем кодом, так как не уверен, что это единственная ошибка, которую я получаю.

Моя цель - вставить строку в файл .png. Я использовал Python около 10 лет назад, я пользователь C #, поэтому извините, если это слишком nooby как вопрос

Спасибо Постскриптум я не очень хорошо выражаюсь, не стесняйтесь редактировать сообщение

from PIL import Image
import binascii
import optparse

def rgb2hex(r, g, b):
    return '#{:02x}{:02x}{:02x}'.format(r, g, b)

def hex2rgb(hexcode):
    return tuple(map(ord, hexcode[1:]))

def str2bin(message):
    binary = bin(int(binascii.hexlify(message.encode()), 16))
    return binary[2:]

def bin2str(binary):
    message = binascii.unhexlify('%x' % (int('0b' + binary, 2)))
    return message

def encode(hexcode, digit):
    if hexcode[-1] in ('0', '1', '2', '3', '4', '5'):
        hexcode = hexcode[:-1] + digit
        return hexcode
    else:
        return None


def decode(hexcode):
    if hexcode[-1] in ('0', '1'):
        return hexcode[-1]
    else:
        return None


def hide(filename, message):
    img = Image.open(filename)
    binary = str2bin(message) + '1111111111111110'
    if img.mode in ('RGBA'):
        img = img.convert('RGBA')
        datas = img.getdata()

        newData = []
        digit = 0
        temp = ''
        for item in datas:
            if (digit < len(binary)):
                newpix = encode(rgb2hex(item[0], item[1], item[2]), binary[digit])
                if newpix == None:
                    newData.append(item)
                else:
                    r, g, b = [hex2rgb(newpix)]
                    newData.append((r, g, b, 255))
                    digit =+ 1
            else:
                newData.append(item)
        img.putdata(newData)
        img.save(filename, "PNG")
        return "Completed!"
    return "Incorrect Image mode, couldn't hide"

def retr(filename):
    img = Image.open(filename)
    binary = ''

    if img.mode in ('RGBA'):
        img = img.convert('RGBA')
        datas = img.getdata()

        for item in datas:
            digit = decode(rgb2hex(item[0], item[1], item[2]))
            if digit == None:
                pass
            else:
                binary = binary + digit
                if (binary[-16:] == '1111111111111110'):
                    print("Success")
                    return bin2str(binary[:-16])
        return bin2str(binary)
    return "Incorrect Image mode, couldn't retrieve"

def Main():
    parser = optparse.OptionParser('usage %prog ' + '-e/-d <target file>')
    parser.add_option('-e', dest = 'hide', type = 'string', help = 'target picture path to hide text')
    parser.add_option('-d', dest = 'retr', type = 'string', help = 'target picture to retrieve text')
    (options, args) = parser.parse_args()
    if (options.hide != None):
        text = input("Enter a message to hide: ")
        print(hide(options.hide, text))
    elif(options.retr != None):
        print(retr(optrions.retr))
    else:
        print(parser.usage)
        exit(0)

if __name__ == '__main__':
    Main()

1 Ответ

0 голосов
/ 28 августа 2018
>>> hex2rgb('#abcdef')
(97, 98, 99, 100, 101, 102)

Здесь я использую вашу функцию hex2rgb() без привязки вывода к каким-либо переменным. Он возвращает 6 значений, как и следовало ожидать, поскольку вы декодируете каждый символ из шестнадцатеричного значения (например, a) в целочисленную кодовую точку Юникода, которая соответствует шестнадцатеричному a: 97. ( см. Документацию или ord () здесь )

>>> r,g,b = hex2rgb('#abcdef')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)

При попытке распаковать их в три переменные возникает ошибка, поскольку ваша функция возвращает 6 переменных вместо ожидаемых 3.

>>> r,g,b = [hex2rgb('#abcdef')]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 1)

Ваш подход к переносу 6 целых чисел в список уменьшает возвращаемое значение с 6 переменных до всего 1 значения (список из 6 элементов), и, следовательно, это не решает вашу проблему.

Чтобы решить вашу проблему, вы должны найти способ получить 3 целых числа вместо 6. Для этого вам понадобится другой подход для декодирования вашего значения HEX.

Пары RGB в моем примере состоят из Red = AB, Green = CD, Blue = EF. Используя map() с ord(), вы переводите A и B отдельно в целое число, а это не то, что вам нужно, так как в итоге вы получаете 2 целых числа (97 и 98) вместо 1 целого числа (171), соответствующее значению AB.

Итак, что вы хотите:

>>> int("0xAB",0)
171

Как видите, преобразование AB вместе вернет правильное значение (171). См. этот ответ для примера того, как это сделать. Измените ваш hex2rgb(), чтобы сделать это.

И последнее, но не менее важное: ваш подход к использованию ord() для декодирования символов в целые числа интересен, но может и не быть правильным, поскольку A и a имеют другое значение кодовой точки Unicode (A = 65, a = 97), и поэтому они приводят к различным значениям для вашего цвета. В цветовых кодах HEX нет разницы между прописными и строчными буквами. При использовании метода с int(), как описано выше, результат будет одинаковым для символов в нижнем или верхнем регистре и, следовательно, будет более правильным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...