Kicker mật mã //


12

Kicker mật mã

Một phương pháp phổ biến nhưng không an toàn để mã hóa văn bản là hoán vị các chữ cái trong bảng chữ cái. Nói cách khác, mỗi chữ cái của bảng chữ cái luôn được thay thế trong văn bản bằng một số chữ cái khác. Để đảm bảo mã hóa có thể đảo ngược, không có hai chữ cái nào được thay thế bằng cùng một chữ cái. Nhiệm vụ của bạn là giải mã một số dòng văn bản được mã hóa, giả sử rằng mỗi dòng sử dụng một bộ thay thế khác nhau và tất cả các từ trong văn bản được giải mã là từ một từ điển các từ đã biết.

Đầu vào

Đầu vào bao gồm các từ viết thường, theo thứ tự bảng chữ cái. Những từ này bao gồm từ điển của các từ có thể xuất hiện trong văn bản được giải mã. Theo sau từ điển là một số dòng đầu vào. Mỗi dòng được mã hóa như mô tả ở trên.

Không có hơn 1.000 từ trong từ điển. Không có từ nào vượt quá 16 chữ cái. Các dòng được mã hóa chỉ chứa các chữ cái và dấu cách viết thường và không vượt quá 80 ký tự.

Đầu ra

Giải mã từng dòng và in nó ra đầu ra tiêu chuẩn. Nếu có nhiều giải pháp, bất kỳ một sẽ làm. Nếu không có giải pháp, thay thế mỗi chữ cái trong bảng chữ cái bằng dấu hoa thị.

Đầu vào mẫu

and dick jane puff spot yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd

Đầu ra mẫu

dick and jane and puff and spot and yertle
**** *** **** *** **** *** **** *** ******

Đây là giải pháp. Xin lưu ý rằng tôi không phải là một con ngựa chạy trong cuộc đua cho các byte ngắn nhất / Lập trình viên cạnh tranh. Tôi chỉ thích câu đố!

( Nguồn )


1
Vui lòng thư giãn> đầu vào <ràng buộc của bạn đối với một cái gì đó có thể áp dụng cho từng ngôn ngữ. Ví dụ, rất nhiều ngôn ngữ sẽ ghét và không đánh giá cao định dạng bắt đầu bằng 6. Tôi khuyên bạn nên để định dạng hoàn toàn không xác định và chỉ nói rằng đầu vào là danh sách các từ và danh sách các dòng cần mã hóa.
orlp

Được rồi, bạn đi đây!
Dhruv Ramani

1
Có hạn chế thời gian chạy cho điều này? Tôi có thể chỉ đơn giản lặp đi lặp lại qua mọi kết hợp thay thế có thể, cho đến khi một công việc (có thể sẽ mất nhiều năm để hoàn thành)?
Nathan Merrill

@NathanMerrill Làm điều đó, và nếu phải mất nhiều năm, chỉ cần in nó ở dạng ngôi sao. Vihan, Nó không phải là một bản sao, xin vui lòng đọc câu hỏi đúng.
Dhruv Ramani

Chúng ta có thể chỉ xuất ra các từ hoặc chúng ta phải tham gia chúng?
Hạ cấp

Câu trả lời:


3

Python 3, 423 byte

import sys,re
S=re.sub
D,*L=sys.stdin.read().split('\n')
def f(W,M=[],V="",r=0):
 if len({d for(s,d)in M})==len(M):
  if[]==W:return V.lower()
  for d in D.split():p='([a-z])(?%s.*\\1)';m=re.match(S(p%'=',')\\1=P?(',S(p%'!',').>\\1<P?(',W[0].translate(dict(M))[::-1]))[::-1]+'$',d.upper());r=r or m and f(W[1:],M+[(ord(s),m.group(s))for s in m.groupdict()],V+d+" ")
  return r
for l in L:print(f(l.split())or S('\w','*',l))

Đọc đầu vào từ STDIN và ghi đầu ra vào STDOUT, sử dụng cùng định dạng với đầu vào / đầu ra mẫu.

Giải trình

Đối với mỗi dòng của bản mã, chúng tôi thực hiện quy trình sau:

Chúng tôi giữ một bản đồ, M , trong tất cả các biến đổi chữ cái mà chúng tôi đã thiết lập (ban đầu trống). Chúng tôi làm điều đó theo cách mà các chữ cái nguồn đều là chữ thường và các chữ cái đích đều là chữ hoa.

Chúng tôi xử lý các từ trong bản mã theo thứ tự. Đối với mỗi từ, chúng tôi tìm thấy tất cả các từ trong từ điển có thể phù hợp, như sau:

Giả sử rằng từ của chúng ta, w , là glpplppljjlM chứa quy tắc j -> P. Đầu tiên chúng ta chuyển đổi w bằng cách sử dụng các quy tắc hiện có trong M , nhận glpplpplPPl. Sau đó chúng tôi chuyển đổi w thành regex có hương vị trăn sau đây:

(?P<g>.)(?P<l>.)(?P<p>.)(?P=p)(?P=l)(?P=p)(?P=p)(?P=l)PP(?P=l)

Các quy tắc của chuyển đổi như sau:

  • Sự xuất hiện đầu tiên của mỗi chữ cái viết thường x, được thay thế bằng . Điều này xác định một nhóm bắt giữ được đặt tên, được gọi , phù hợp với một cahracter duy nhất.(?P<x>.)x
  • Mỗi lần xuất hiện tiếp theo, mỗi chữ cái viết thường x, được thay thế bằng . Đây là một phản ứng ngược với nhân vật được nhóm có tên bắt trước .(?P=x)x

Chúng tôi thực hiện chuyển đổi này bằng cách đảo ngược w , sau đó áp dụng hai thay thế regex sau:

s/([a-z])(?!.*\1)/)>\1<P?(/
s/([a-z])(?=.*\1)/)\1=P?(/

và sau đó đảo ngược kết quả. Lưu ý rằng các ký tự được chuyển đổi trước đó bởi M xuất hiện dưới dạng chữ hoa và do đó không thay đổi.

Chúng tôi kết hợp regex kết quả với từng từ trong từ điển, trong đó các từ trong từ điển xuất hiện dưới dạng chữ hoa. Ví dụ, regex ở trên sẽ khớp với từ này MISSISSIPPI. Nếu chúng ta tìm thấy một trận đấu, chúng tôi trích xuất các quy tắc chuyển đổi mới từ nó, và thêm chúng vào M . Các quy tắc chuyển đổi mới chỉ đơn giản là các ký tự được bắt bởi mỗi nhóm bắt giữ. Trong regex ở trên, các gtrận đấu Mnhóm , ltrận đấu nhóm Iptrận đấu nhóm S, cho chúng ta các quy tắc g -> M, l -> I, p -> S. Chúng ta phải đảm bảo rằng các quy tắc kết quả là nhất quán, nghĩa là không có hai chữ cái nguồn ánh xạ tới cùng một chữ cái đích; nếu không, chúng tôi từ chối trận đấu.

Sau đó chúng tôi tiến hành từ tiếp theo, sử dụng các quy tắc chuyển đổi tăng cường. Nếu chúng ta có thể kết hợp tất cả các từ mã hóa bằng quy trình này, chúng ta đã giải mã được văn bản. Nếu chúng tôi không thể ghép một từ với bất kỳ từ nào trong từ điển, chúng tôi sẽ quay lại và cố gắng khớp các từ trước đó với các từ trong từ điển khác nhau. Nếu quá trình này thất bại, không có giải pháp và chúng tôi in một hàng dấu hoa thị.


2

CJam, 62 56 byte

qN%Sf/(f{\:C,m*{C..+`Sa`m2/Q|z_''f-Qf|=},C:,'*f*a+0=S*N}

Khá chậm và đói bộ nhớ, nhưng hoạt động cho trường hợp thử nghiệm với trình thông dịch Java.

Chạy ví dụ

$ cat input; echo
and dick jane puff spot yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd
$ time cjam kicker.cjam < input
dick and jane and puff and spot and yertle
**** *** **** *** **** *** **** *** ******

real    5m19.817s
user    6m41.740s
sys     0m1.611s
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.