Как дешифровать текст?
Есть код, который шифрует текст (текст разбивается на группы из 5 элементов, в каждой группе символы записываются в обратном порядке, далее переставляются сами группы символов). Нужно дешифровать, то есть вернуть исходный текст.
s = input('Введите строку: ')
# убираем все знаки препинания и тд., оставляем только буквы и цифры
s = ''.join(e for e in s if e.isalnum())
# разделим на части и сразу развернем текст
s = [s[i:i+5][::-1] for i in range(0, len(s), 5)]
# теперь развернем группы
random.shuffle(s)
print(s)
Ответы (1 шт):
Автор решения: KABAN PUNK
→ Ссылка
Наслаждайтесь :)
Единственное, нужно передовать ключ. В роли ключа здесь выступает набор из 624 целых чисел в диапазоне от 0 до 4294967294. Они используются для составления матрицы Мерсенна, по которой, в последствии, прогнозируются случайные числа, используемые в шифровании.
Ваш алгоритм шифрования я не менял, только добавил дешифровку.
import random, time
'''
------------------------------ ENCODE ------------------------------
'''
class Encoder():
def __init__(self):
self.key = []
def castom_shuffle(self, lst):
for i in range(len(lst)-1, 0, -1):
j = random.randint(0, i)
lst[i], lst[j] = lst[j], lst[i]
def encode(self, text):
if not text:
raise ValueError("Unable to encrypt blank text")
s = ''.join(e for e in text if e.isalnum())
s = [s[i:i+5][::-1] for i in range(0, len(s), 5)]
for i in range(624):
self.key.append(random.getrandbits(32))
self.castom_shuffle(s)
return ' '.join(s), self.key
'''
------------------------------ DECODE ------------------------------
'''
class Decoder:
def __init__(self, key):
self.counter = 0
self.mt = []
self.state = False
for i in key:
self.submit(i)
def decode(self,text):
s = text.split()
self.predict_shuffle(s)
return ''.join([i[::-1] for i in s])
def submit(self, num):
if self.state:
raise ValueError("Already got enough bits")
bits = self._to_bitarray(num)
assert (all([x == 0 or x == 1 for x in bits]))
self.counter += 1
self.mt.append(self._harden_inverse(bits))
if self.counter == 624:
self._regen()
self.state = True
def _predict_32(self):
if not self.state:
raise ValueError("Didn't recieve enough bits to predict")
if self.counter >= 624:
self._regen()
self.counter += 1
return self._harden(self.mt[self.counter - 1])
def predict_getrandbits(self, k):
if not self.state:
raise ValueError("Didn't recieve enough bits to predict")
if k == 0:
return 0
words = (k - 1) // 32 + 1
res = []
for i in range(words):
r = self._predict_32()
if k < 32:
r = [0] * (32 - k) + r[:k]
res = r + res
k -= 32
return self._to_int(res)
def predict_randbelow(self, n):
k = n.bit_length()
r = self.predict_getrandbits(k)
while r >= n:
r = self.predict_getrandbits(k)
return r
def predict_randrange(self, start, stop=None, step=1, _int=int):
istart = _int(start)
if istart != start:
raise ValueError("non-integer arg 1 for randrange()")
if stop is None:
if istart > 0:
return self.predict_randbelow(istart)
raise ValueError("empty range for randrange()")
istop = _int(stop)
if istop != stop:
raise ValueError("non-integer stop for randrange()")
width = istop - istart
if step == 1 and width > 0:
return istart + self.predict_randbelow(width)
if step == 1:
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
istep = _int(step)
if istep != step:
raise ValueError("non-integer step for randrange()")
if istep > 0:
n = (width + istep - 1) // istep
elif istep < 0:
n = (width + istep + 1) // istep
else:
raise ValueError("zero step for randrange()")
if n <= 0:
raise ValueError("empty range for randrange()")
return istart + istep * self.predict_randbelow(n)
def predict_randint(self, a, b):
return self.predict_randrange(a, b + 1)
def predict_shuffle(self, seq):
rr = [self.predict_randint(0, i) for i in range(len(seq)-1, 0, -1)]
rr.reverse()
for i in range(1,len(seq)):
j = rr[i-1]
seq[i], seq[j] = seq[j], seq[i]
def _to_bitarray(self, num):
k = [int(x) for x in bin(num)[2:]]
return [0] * (32 - len(k)) + k
def _to_int(self, bits):
return int("".join(str(i) for i in bits), 2)
def _or_nums(self, a, b):
if len(a) < 32:
a = [0] * (32 - len(a)) + a
if len(b) < 32:
b = [0] * (32 - len(b)) + b
return [x[0] | x[1] for x in zip(a, b)]
def _xor_nums(self, a, b):
if len(a) < 32:
a = [0] * (32 - len(a)) + a
if len(b) < 32:
b = [0] * (32 - len(b)) + b
return [x[0] ^ x[1] for x in zip(a, b)]
def _and_nums(self, a, b):
if len(a) < 32:
a = [0] * (32 - len(a)) + a
if len(b) < 32:
b = [0] * (32 - len(b)) + b
return [x[0] & x[1] for x in zip(a, b)]
def _decode_harden_midop(self, enc, and_arr, shift):
NEW = 0
XOR = 1
OK = 2
work = []
for i in range(32):
work.append((NEW, enc[i]))
changed = True
while changed:
changed = False
for i in range(32):
status = work[i][0]
data = work[i][1]
if i >= 32 - shift and status == NEW:
work[i] = (OK, data)
changed = True
elif i < 32 - shift and status == NEW:
if and_arr[i] == 0:
work[i] = (OK, data)
changed = True
else:
work[i] = (XOR, data)
changed = True
elif status == XOR:
i_other = i + shift
if work[i_other][0] == OK:
work[i] = (OK, data ^ work[i_other][1])
changed = True
return [x[1] for x in work]
def _harden(self, bits):
bits = self._xor_nums(bits, bits[:-11])
bits = self._xor_nums(bits, self._and_nums(bits[7:] + [0] * 7, self._to_bitarray(0x9d2c5680)))
bits = self._xor_nums(bits, self._and_nums(bits[15:] + [0] * 15, self._to_bitarray(0xefc60000)))
bits = self._xor_nums(bits, bits[:-18])
return bits
def _harden_inverse(self, bits):
bits = self._xor_nums(bits, bits[:-18])
bits = self._decode_harden_midop(bits, self._to_bitarray(0xefc60000), 15)
bits = self._decode_harden_midop(bits, self._to_bitarray(0x9d2c5680), 7)
bits = self._xor_nums(bits, [0] * 11 + bits[:11] + [0] * 10)
bits = self._xor_nums(bits, bits[11:21])
return bits
def _regen(self):
N = 624
M = 397
MATRIX_A = 0x9908b0df
LOWER_MASK = 0x7fffffff
UPPER_MASK = 0x80000000
mag01 = [self._to_bitarray(0), self._to_bitarray(MATRIX_A)]
l_bits = self._to_bitarray(LOWER_MASK)
u_bits = self._to_bitarray(UPPER_MASK)
for kk in range(0, N - M):
y = self._or_nums(self._and_nums(self.mt[kk], u_bits), self._and_nums(self.mt[kk + 1], l_bits))
self.mt[kk] = self._xor_nums(self._xor_nums(self.mt[kk + M], y[:-1]), mag01[y[-1] & 1])
for kk in range(N - M - 1, N - 1):
y = self._or_nums(self._and_nums(self.mt[kk], u_bits), self._and_nums(self.mt[kk + 1], l_bits))
self.mt[kk] = self._xor_nums(self._xor_nums(self.mt[kk + (M - N)], y[:-1]), mag01[y[-1] & 1])
y = self._or_nums(self._and_nums(self.mt[N - 1], u_bits), self._and_nums(self.mt[0], l_bits))
self.mt[N - 1] = self._xor_nums(self._xor_nums(self.mt[M - 1], y[:-1]), mag01[y[-1] & 1])
self.counter = 0
enc = Encoder()
enc_text, key = enc.encode('случайности не случайны')
dec = Decoder(key)
print(dec.decode(enc_text))