Như thể thách thức này có thể là tinh thần Pythonesque hơn nữa ... Không cần có kiến thức trước về chuỗi Markov hoặc kỹ thuật mã hóa.
Bạn là một điệp viên cần lấy một số thông tin quan trọng từ dịch vụ bảo mật M1S của Anh. Các nhân viên của M1S nhận thức rõ rằng tín hiệu Wi-Fi của họ có thể bị chặn, các lỗ hổng bảo mật Android / iOS của họ bị khai thác, v.v., vì vậy tất cả đều sử dụng Nokia 3310 để truyền thông tin văn bản được nhập bằng tính năng tự động hoàn thành T9 .
Trước đây bạn đã hack điện thoại để giao cho cơ quan tình báo và đã cài đặt keylogger dưới bàn phím nhựa vinh quang của họ, vì vậy bây giờ bạn nhận được chuỗi số tương ứng với các chữ cái họ đã nhập, vì vậy, đại bàng đã rời khỏi tổ cảnh báo các đặc vụ .
84303245304270533808430637802537808430243687
Nhưng chờ đã! Một số trình tự T9 không rõ ràng (có thể là tên gọi là mật mã, có thể là tên của tên, chữ viết tắt, chữ viết tắt, chữ viết tắt, chữ viết tắt, chữ viết càng khó hiểu, nó càng bị nghi ngờ!), Vậy bạn sẽ làm gì? Bạn biết rằng bài kiểm tra đầu vào duy nhất mà M1S sử dụng là tóm tắt kiệt tác của Marcel Proust, Hồi ức về những điều đã qua trong 15 giây, vì vậy bạn muốn chọn từ tiếp theo sau bài trước theo phân phối tần số của nó trong toàn bộ đầu bếp-d ' œuvre của Proust!
Bạn có thể crack mã và có được những gì có thể là thông điệp ban đầu?
Nguyên tắc của T9
Cơ chế tự động hoàn thành T9 có thể được mô tả như sau. Nó ánh xạ các ký tự chữ cái thành các số như trong hình trên.
abc -> 2
def -> 3
ghi -> 4
jkl -> 5
mno -> 6
pqrs -> 7
tuv -> 8
wxyz -> 9
<space> -> 0
<other> -> <is deleted>
Bộ giải mã T9 nhận được một chuỗi các chữ số và cố gắng đoán từ có thể được gõ bằng các phím nhấn đó. Nó có thể sử dụng bảng tần số tiêu chuẩn, nhưng chúng tôi sẽ tiến thêm một bước và dự đoán từ tiếp theo bằng chuỗi Markov!
Học mẫu
Các corpus là phiên bản này nặng nề tước “Remembrance of Things Past” Proust của ( s/-/ /g
, s/['’]s //g
và s/[^a-zA-Z ]//g
- begone bối rối sở hữu 's
!) Ban đầu được công bố trên Đại học Adelaide trang web (các văn bản của tác phẩm này là trong phạm vi công cộng tại Úc).
Toàn bộ văn bản phải được phân tích thành một chuỗi, dưới dạng một câu dài, dưới dạng một vectơ dài của từ (bất kỳ ngôn ngữ nào thuận tiện hơn cho ngôn ngữ của bạn), loại bỏ các ngắt dòng và chia thành các từ tại các khoảng trắng . (Tôi không cung cấp tệp một đoạn vì các công cụ github có thể bị nhăn mặt.)
Làm cách nào để đọc toàn bộ văn bản dưới dạng một chuỗi / câu? Một ví dụ trong R :
p_raw <- read.table("proust.txt", sep="\t") # Because there are no tabs
p_vec <- as.character(p_raw$V1) # Conversion to character vector
p_str <- paste(p_vec, collapse=" ") # One long string with spaces
p_spl <- strsplit(p_str, split=" ")[[1]] # Vector of 1360883 words
proust <- p_spl[p_spl!=""] # Remove empty entries — 1360797
Bài tập
Đưa ra một chuỗi các chữ số dưới dạng một số, trả về một chuỗi văn bản có thể có thể được gõ bằng các phím T9 tương ứng bằng chuỗi xác suất để dự đoán từ X tiếp theo dựa trên văn bản đào tạo này được coi là một câu dài.
Nếu X là từ T9 đầu tiên của văn bản và có nhiều lần đoán, hãy chọn một từ ngẫu nhiên, nếu không thì chỉ chọn một từ có thể.
Đối với tất cả các từ T9 tiếp theo X (i) đứng trước một từ đã được giải mã w (i-1) :
- Nếu một T9 từ X có thể được chuyển đổi thành một từ x bình thường theo một cách duy nhất, hãy làm điều đó.
- Nếu có nhiều tùy chọn chuyển đổi có sẵn cho X , giả sử x1, x2, ... , hãy tìm từ đã đoán trước w .
- Nếu w không bao giờ được theo sau bởi bất kỳ thứ gì ánh xạ tới X trong tác phẩm gốc của Proust, hãy chọn bất kỳ x1, x2, ... nào có thể ngẫu nhiên.
- Nếu w X luôn tương ứng với w x1 trong bản gốc và không có xi xi đồng thời có thể được ánh xạ vào X , hãy chọn x1 .
- Nếu w X có thể được chuyển đổi thành w x1 , w x2 , ... có thể tìm thấy trong kho văn bản, thì hãy đếm tất cả các xi xi có thể theo w và ánh xạ tới X trong kho và chọn xi với xác suất xi / (x1 + x2 + ...) .
Ví dụ 2a. Nếu thông điệp là 76630489
, nơi 489
có thể guy
hoặc ivy
(chúng xảy ra trong kho ít nhất một lần), 7663
có thể được giải mã thành some
(một từ đầu tiên rất có thể xảy ra). Nếu some
không bao giờ được theo sau bởi bất cứ thứ gì ánh xạ 489
vào kho văn bản, sau đó chọn guy
hoặc ivy
ngẫu nhiên với xác suất 0,5.
Ví dụ 2b. Nếu thông điệp là 766302277437
, nơi 2277437
có thể barrier
hoặc carrier
, 7663
có thể được giải mã là some
. Nếu Proust luôn được sử dụng some carrier
và không bao giờ some barrier
, sau đó chọn some carrier
.
Ví dụ 2c. Giả sử bạn muốn giải mã chuỗi 536307663
. 5363
đã được dự đoán là lend
. 7663
có thể là bất kỳ những: pond
, roof
và some
. Bạn đếm số lần xuất hiện của từ sau lend
trong kho mẫu. Giả sử bạn nhận được một cái gì đó như thế này (chỉ để minh họa):
T9 Word following lend Occurrences
7663 some 7
7663 pond 2
7663 roof 1
Vì vậy, nếu 7663
được đi trước lend
, có 7/(7+2+1)=70%
xác suất 7663
là some
20% pond
và 10% roof
. Thuật toán của bạn sẽ tạo ra lend some
70% trường hợp, lend pond
trong 20% trường hợp, v.v.
Bạn có thể giả định một cách an toàn rằng các tác nhân chỉ sử dụng các chữ cái và dấu cách az (không có dấu chấm câu, không sở hữu 's
và không có số).
Bạn cũng có thể cho rằng các tác nhân của M1S không bao giờ sử dụng bất kỳ từ nào ngoài phạm vi của Remembrance of Things Past dòng (vốn là một từ vựng khổng lồ của 29.237 từ!).
Tính chất giả tưởng T9 đã được thực hiện trong thử thách này , vì vậy bạn có thể xem qua nó.
Nếu bạn cần bất kỳ sự giúp đỡ, chuỗi xác suất được hoành tráng thuần hóa trong này , đó và sau thử thách, nhưng bạn thậm chí không cần phải biết nguyên tắc của chuỗi như vậy: tất cả những gì được nêu trong công việc.
Các trường hợp thử nghiệm
--Inputs--
20784250276960369
20784250276960369
84303245304270533808430637802537808430243687
94280343084306289072908608430262780482737
94280343084306289072908608430262780482737
--Possible outputs--
c quick brown fox
a stick crown fox
the eagle gas left the nest blest vie agents
what did the navy pay to the coast guards
what did the navy raz un the coast guards
Quy tắc:
- Tiêu chuẩn áp dụng.
- Bạn không biết tin nhắn gốc, tất cả những gì bạn nhận được là một chuỗi các chữ số và tệp proust.txt mà bạn chỉ cần tải trong bộ nhớ / không gian làm việc / bất cứ thứ gì. Không cần phải có bất cứ điều gì khép kín; giả định
proust.txt
luôn luôn có thể truy cập. - Thuật toán của bạn phải có khả năng tạo ra các kết quả đầu ra khác nhau với xác suất tương ứng nếu có nhiều hơn một tùy chọn giải mã có thể xảy ra theo kho văn bản (xem Ví dụ 2c).
Bạn cần giữ kín đáo nhất có thể, để mã ngắn nhất sẽ thắng!
PS Lợi ích rõ ràng của thuật toán xác suất này là thực tế là xác suất bạn sẽ có được một chuỗi gốc thực sự cho một chuỗi được giải mã mơ hồ có xu hướng một - chỉ cần chờ ...
PPS Xem thêm Dự đoán bằng cách khớp một phần .