Rot18, шифрование и дешифрование (python, Sublime Text) - PullRequest
0 голосов
/ 14 марта 2020

Я ищу плагин, который может шифровать / дешифровать текст с использованием rot18 в Sublime Text v3.2.2.

Я пробовал этот урок (только rot13), но он не работает для меня: https://www.sublimetext.com/docs/plugin-examples

Я перепробовал много плагинов, и единственный, который отлично работает: (к сожалению, это rot47)

import sublime
import sublime_plugin

class Rot47Command(sublime_plugin.TextCommand):
    def run(self, edit):
        for region in self.view.sel():
            if not region.empty():
                s = self.view.substr(region)
                s = ''.join(chr(33 + ((ord(ch) + 14) % 94)) for ch in s)
                self.view.replace(edit, region, s)

У кого-нибудь есть какой-нибудь функциональный плагин на rot18 пожалуйста?

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

Вы не указываете, но я предполагаю, что вы используете ROT-18 в наборе символов 0..9, A..Z, который составляет 36 символов. 36/2 = 18, следовательно, ROT-18.

ROT-13 работает с 26 символами алфавита c: 26/2 = 13. Вы хотите адаптировать его к ROT-18.

Основное отличие состоит в том, что символы алфавита c являются непрерывными в наборе символов ASCII, и это предположение встроено в код, из которого вы копируете. То же самое верно для ROT-47; используемые символы ASCII являются непрерывными. В ROT-18 цифры 0,9 и символы алфавита c, A..Z не являются непрерывными в ASCII. Между ними есть разрыв от : (# 58) до @ (# 64). Коды ASCII в этом регионе не являются ни цифрами, ни буквами.

Одним из решений является создание собственного массива, а не в порядке ASCII, где эти два являются непрерывными: [0, 1, ... 9, A, B, ... Z]. Напишите вашу программу для работы с этим массивом.

В качестве альтернативы вы можете работать с кодами ASCII, обрабатывая коды от # 58 до # 64 специально, чтобы сдвиг прошел правильно.

Первый вариант возможно, проще, и код будет больше похож на пример ROT-13. Основным отличием будет замена функции ord(), которая возвращает код ASCII, эквивалентной функцией, задающей позицию в вашем массиве.

2 голосов
/ 14 марта 2020

Вы можете адаптировать свой код. Вот как работает rot_N:

Это диапазон ASCII до 127:

a = 32  
for k in range(0,16):
    print(a+k, chr(a+k), "    ", a+16+k, chr(a+16+k), "    ", a+32+k, chr(a+32+k), "    ", 
          a+48+k, chr(a+48+k), "    ", a+64+k, chr(a+64+k), "    ", a+80+k, chr(a+80+k))

    #    32        48 0      64 @      80 P       96 `      112 p
    #    33 !      49 1      65 A      81 Q       97 a      113 q
    #    34 "      50 2      66 B      82 R       98 b      114 r
    #    35 #      51 3      67 C      83 S       99 c      115 s
    #    36 $      52 4      68 D      84 T      100 d      116 t
    #    37 %      53 5      69 E      85 U      101 e      117 u
    #    38 &      54 6      70 F      86 V      102 f      118 v
    #    39 '      55 7      71 G      87 W      103 g      119 w
    #    40 (      56 8      72 H      88 X      104 h      120 x
    #    41 )      57 9      73 I      89 Y      105 i      121 y
    #    42 *      58 :      74 J      90 Z      106 j      122 z
    #    43 +      59 ;      75 K      91 [      107 k      123 {
    #    44 ,      60 <      76 L      92 \      108 l      124 |
    #    45 -      61 =      77 M      93 ]      109 m      125 }
    #    46 .      62 >      78 N      94 ^      110 n      126 ~
    #    47 /      63 ?      79 O      95 _      111 o      127 

ROT n означает, что вместо этого вы берете букву chr(ord(l)+n). Вы должны быть осторожны при обтекании.

Для расчета rot_N базовая форма c:

def rot_N(n,letter):
    return chr( (ord(letter)-32+n) % (128-32) + 32)    # 128-32 = 96

Вы можете проверить это с помощью:

k="Hello Zzzzz"
print( ''.join(rot_N(18, l) for l in k))   # schould give you a tranlation
print( ''.join(rot_N(0, l) for l in k))    # should give the exact text

и проверьте обратное с помощью:

k_inverse ="Zw~~!2l,,,,"
print( ''.join(rot_N(-18, l) for l in k_inverse))   # use -18 here
print( ''.join(rot_N(0, l) for l in k_inverse)) 

Если вы замените

s = ''.join(chr(33 + ((ord(ch) + 14) % 94)) for ch in s)

на

s = ''.join(rot_N(18, ch) for ch in s)) 

, все будет в порядке.

...