Кодирование файла с помощью функции ord - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь закодировать файл и вывести кодирование в новый файл, но я получил эту ошибку:

TypeError: ord() expected string of length 1, but int found

Мой код:

from sys import argv, exit


def encode(data):
    encoded = ''
    while data:
        current = data[0]
        count = 1
        for i in data[1:]:
            if i == current:
                count += 1
            else:
                break
            if count == 255:
                break

        encoded += '{}{}'.format(chr(ord(current) & 255), chr(count & 255)) #error occurs here.
        data = data[count:]

    return encoded


if __name__ == '__main__':
    if len(argv) < 2:
        print('Please specify input file!')
        exit(0)
    with open(argv[1], 'rb') as (f):
        data = f.read()
    with open(argv[1] + '.out', 'wb') as (f):
        f.write(encode(data))

Дополнительный вопрос: Как мне декодировать закодированный файл?

1 Ответ

0 голосов
/ 28 апреля 2020

Вы читаете байты (open(..., 'rb')), поэтому, когда вы берете один элемент строки байтов, вы получаете байт ie. число. Этот номер уже является символьным кодом, поэтому просто пропустите ord. Кроме того, вы можете открыть файл без модификатора b (open(..., 'r')), который будет возвращать строку; Я бы посоветовал сохранить ее как байтовую строку (или вы можете столкнуться с проблемами кодирования, если анализируете что-то не-ascii).

Вы столкнетесь с аналогичной проблемой при сохранении файла: вы не можете написать строка в файл, открытый с модификатором b. Поскольку у вас есть символы вне диапазона ascii (> 128), запись в виде строки не является хорошей идеей, так как python попытается закодировать ваши символы (например, в UTF-8), и вы получите совершенно другой байт. Следовательно, наилучшее решение, вероятно, состоит не в том, чтобы объединить ваши данные в строку в вашем l oop (часть, где вы делаете '{}{}'.format(...), а в том, чтобы иметь список (encoded = [], соответствующий с encoded.append(current)) и преобразовать это в байтовую строку, используя bytes(encoded) после вашего l oop. Затем вы можете без проблем передать его в write.

Что касается того, как декодировать ваш файл, вы можете просто открыть файл, как вы сделать для кодирования, прочитать два байта b1 и b2 и добавить [b1]*b2 к вашему выводу (опять же, как список), и преобразовать это в байтовую строку с bytes().

...