Сделать DES применимым к русскому алфавиту

Имеется код с гитхаба, реализующий DES: https://github.com/RobinDavid/pydes/blob/master/pydes.py

Есть задание сделать его применяемым к русскому алфавиту. Насколько я понял, данный код его не поддерживает, потому что работает с символами по одному байту:

def string_to_bit_array(text):#Convert a string into a list of bits
    array = list()
    for char in text:
        binval = binvalue(char, 8)#Get the char value on one byte
        array.extend([int(x) for x in list(binval)]) #Add the bits to the final list
    return array

def bit_array_to_string(array): #Recreate the string from the bit array
    res = ''.join([chr(int(y,2)) for y in [''.join([str(x) for x in _bytes]) for _bytes in  nsplit(array,8)]])   
    return res

def binvalue(val, bitsize): #Return the binary value as a string of the given size 
    binval = bin(val)[2:] if isinstance(val, int) else bin(ord(val))[2:]
    if len(binval) > bitsize:
        raise "binary value larger than the expected size"
    while len(binval) < bitsize:
        binval = "0"+binval #Add as many 0 as needed to get the wanted size
    return binval

def nsplit(s, n):#Split a list into sublists of size "n"
    return [s[k:k+n] for k in range(0, len(s), n

 if padding and action==ENCRYPT:
        self.addPadding()
    elif len(self.text) % 8 != 0:#If not padding specified data size must be multiple of 8 bytes
        raise "Data size should be multiple of 8"
    
    self.generatekeys() #Generate all the keys
    text_blocks = nsplit(self.text, 8) #Split the text in blocks of 8 bytes so 64 bits
    result = list()

def addPadding(self):#Add padding to the datas using PKCS5 spec.
    pad_len = 8 - (len(self.text) % 8)
    self.text += pad_len * chr(pad_len)

Я попробовал изменить это на работу 16 (заменил значения 8 на 16) битовыми символами, но в случае с включенным заполнением расшифрованное сообщение становится пустым, а с выключенным строка про кратность сообщения всегда вызывает ошибку. Если ее игнорировать, то расшифровывается только первые 4 байта сообщения (русский алфавит работает).


Ответы (1 шт):

Автор решения: Roman Konoval

Проблема в этой реализации в том, что много манипуляций проводится со строкой, предполагая что один символ будет преобразован в один байт, а преобразование в байты делается на позднем этапе.

То есть сначала делается выравнивание в addPadding используя длину строки в символах len(self.text), потом разбиение на блоки опять же символов. При преобразовании не ASCII в байты, что выравнивание, что длина блоков могут измениться.

Чтоб исправить вам нужно самым первым шагом сделать преобразование в байты (используя аналог string_to_bit_array, который строку закодирует и кодиовка не имеет значения, главное чтоб при расшифровке использовать ее же, когда будете декодировать байты обратно в строку) и уже потом выравнивание и разбиение на блоки делать с байтами.

→ Ссылка