Как зашифровать UTF-8 помимо A-Z в python? - PullRequest
3 голосов
/ 22 апреля 2019

Много лет назад я создал на C # программу для Windows, которая "шифрует" текстовые файлы с помощью (как я думал, был) caeser chipher.

В то время я хотел больше символов, чем просто A-Z, 0-9, и сделал это возможным, но никогда не думал о реальной теории, стоящей за этим.

Глядя на некоторые файлы и сравнивая их с на этом сайте , кажется, что UTF-8 смещается.


Я запустил виртуальную машину Windows (потому что сейчас использую Linux) и набрал: abcdefghijklmnopqrstuvwxyz

Сгенерирован текст, который выглядит следующим образом в шестнадцатеричном формате (сдвинуто 15 раз):

70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f c280 c281 c282 c283 c284 c285 c286 c287 c288 c289

Как мне сместить шестнадцатеричные числа, чтобы они выглядели так?

61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a

Или есть какие-то более простые / лучшие способы сделать это?


UPDATE

Я использую Python 3.5.3, и этот код у меня есть:

import sys

arguments = sys.argv[1:]
file = ""

for arg in arguments:
    if arg[0] != "-":
        file = arg

lines = []
with open(file) as f:
    lines = f.readlines()

for line in lines:
    result = 0
    for value in list(line):
        #value = "0x"+value
        temp=value.encode('utf-8').hex()
        temp+=15
        if(temp>0x7a):
            temp-=0x7a
        elif(temp<=0):
            temp+=0x7a
        #result = result + temp
    print (result)

К сожалению, на данный момент у меня нет исходного кода на C #. Я могу попытаться найти это

Ответы [ 3 ]

2 голосов
/ 22 апреля 2019

Предполагая, что вы вводите текст ASCII, самое простое решение - это кодировать / декодировать как ASCII и использовать встроенные методы ord() и chr() для преобразования из символьного в байтовое значение и наоборот.

Обратите внимание, что значение temp не может быть меньше 0, поэтому второй оператор if можно удалить.

NB. Это выходит за рамки вопроса, но я также заметил, что вы сами разбираете аргументы. Я настоятельно рекомендую использовать argparse вместо этого, так как это очень просто и дает вам намного больше бесплатно (то есть, он выполняет проверку ошибок и выводит хорошее справочное сообщение, если вы запускаете приложение с опцией --help). Смотрите пример кода ниже:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument(dest='filenames', metavar='FILE', type=str, nargs='+',
                    help='file(s) to encrypt')
args = parser.parse_args()

for filename in args.filenames:
    with open(filename, 'rt', encoding='ascii') as file:
        lines = file.readlines()
    for line in lines:
        result = ""
        for value in line:
            temp = ord(value)  # character to int value
            temp += 15
            if temp > 0x7a:
                temp -= 0x7a
            result += chr(temp)  # int value to character
        print(result)
1 голос
/ 22 апреля 2019

Вы можете конвертировать шестнадцатеричные числа между целыми числами и шестнадцатеричными , используя int() и hex().Однако метод hex() работает только с целыми числами.Итак, сначала вам нужно преобразовать в целое число, используя base = 16.

hex_int = int(hex_str, 16)
cipher = hex_int - 15
hex_cipher = hex(cipher)

Теперь примените это в цикле, и вы можете сдвигать результаты влево или вправо по своему усмотрению.И вы можете, конечно, также сжать код.

result = hex(int(hex_string, 16) - 15)

#in a loop
hexes = ['70', '71', 'c280']
ciphered = []
for n in hexes:
    ciphered.append(hex(int(n, 16) - 15))
0 голосов
/ 22 апреля 2019

Вы можете использовать int('somestring'.encode('utf-8').hex(),16), чтобы получить точные значения на этом сайте.Если вы хотите применить одинаковые правила к каждому персонажу, вы можете сделать это в списке персонажей.Вы можете использовать

import codecs

def myencode(character,diff):
    temp=int(character.encode('utf-8').hex(),16)
    temp+=diff
    if(temp>0x7a):
        temp-=0x7a
    elif(temp<=0):
        temp+=0x7a
    result=codecs.decode(hex(temp)[2:],"hex").decode("utf-8")
    return result

diff должен быть сдвиг для шифра (это может быть целое число).encode('utf-8') преобразует строку в байтовый массив, а .hex() отображает байты в шестнадцатеричном виде.Вы должны передавать эту функцию только по одному символу строки за раз, чтобы не было проблем со сдвигом всего.

После того, как вы закончили с кодировкой, вам нужно декодировать ее в новый символ, который вы можете сделатьпо библиотеке codecs для преобразования из целого числа в byte (char), а затем вернуть его обратно в строку с decode("utf-8")

Редактировать: Обновлено, теперь это работает.

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