Home > Net >  Python file encrypting
Python file encrypting

Time:10-19

I am trying to write a program that will encrypt a file by using the .read() function on the file content, which returns 98\xf1\xc6}xb1\*.... I am trying to encrypt the file by looping through each character an incrementing its decimal number by 1 (numbers range from 0 -> 255). and then adding each incremented number to a new list.

new list looks something like this:

['«', 'û', '$', '\x00', 'Ú']...

How do i convert this new list into a format which can be written in binary mode?

class Encrypting():

    def __init__(self):
        self.file = "files/test_img.jpg" 


    def open_file(self):
        f = open(self.file, "rb")
        self.content = f.read()
        print(self.content)
        f.close()


    def convert_file_data(self):
        self.new_values = []
        for i in self.content:
            new_val = i   1
            if i == 255:
                new_val = 0
            new_val = chr(new_val)
            self.new_values.append(new_val)


    def rewrite(self):          
        f = open("files/conv1.jpg", "wb")
        f.write(self.new_values)
        f.close()


def main():
    encrypt = Encrypting()
    encrypt.open_file()
    encrypt.convert_file_data()
    encrypt.rewrite()

if __name__ == "__main__":
     main()

CodePudding user response:

You could change:

f.write(self.new_values) 

to:

f.write(''.join(self.new_values).encode('latin-1'))

combining the list of str into a single str, then encoding it to latin-1 (which is the 1-1 mapping of the first 256 Unicode ordinals to bytes of the same values).

But the real solution is to change:

def convert_file_data(self):
    self.new_values = []
    for i in self.content:
        new_val = i   1
        if i == 255:
            new_val = 0
        new_val = chr(new_val)
        self.new_values.append(new_val)

to:

def convert_file_data(self):
    self.new_values = bytearray()  # A mutable sequence of bytes, ints in range(256), so no type conversions needed
    for i in self.content:
        new_val = i   1
        if i == 255:
            new_val = 0
        # chr conversion is unnecessary and counter-productive, so we just append the new byte
        self.new_values.append(new_val)

This part:

        new_val = i   1
        if i == 255:
            new_val = 0

could be simplified to:

        new_val = (i   1) % 256

as well, which could then simplify the whole function to:

def convert_file_data(self):
    self.new_values = bytearray()  # A mutable sequence of bytes, ints in range(256), so no type conversions needed
    for i in self.content:
        self.new_values.append((i   1) % 256)

or even shorter, a simple genexpr fed to the bytes/bytearray constructor:

def convert_file_data(self):
    self.new_values = bytes((i   1) % 256 for i in self.content)

Any of the bytes or bytearray based solutions are superior to storing a list of str in that:

  1. They require far less memory (the length one strs are likely cached, but the pointers to them stored in the list require 4-8 bytes a piece, vs. just one byte a piece for the raw bytes)
  2. It's less CPU intensive (appending individual bytes is cheaper, and there's no additional costs at the end to rejoin and encode the data, it's already in the correct form natively)
  • Related