Viết một bộ mã hóa VIC


18

Các mật mã VIC là một trong những thuật toán mã hóa bút chì và giấy phức tạp nhất từng được phát minh ra. Được sử dụng vào những năm 1950 bởi điệp viên Liên Xô Reino Häyhänen, tên mã là "VICTOR", nguyên tắc chính của nó là bảo mật thông qua obfuscation; một nhiều obfuscation.

Nhiệm vụ của bạn là viết một chương trình hoặc chức năng sẽ nhận một tin nhắn và mã hóa nó bằng mật mã VIC. Tôi cũng đã đăng một thử thách giải mã mật mã VIC ở đây . Nếu bất kỳ hướng dẫn nào sau đây không rõ ràng, đừng ngần ngại hỏi về chúng trong các bình luận. Các hướng dẫn được điều chỉnh từ trang web này .

Mã hóa mật mã VIC

Sự chuẩn bị

Bạn sẽ cần năm đầu vào:

  • tin nhắn văn bản
  • một từ khóa ngắn hoặc cụm từ chứa các chữ cái phổ biến nhất trong ngôn ngữ của bạn
  • một cụm từ chính, chẳng hạn như một trích dẫn hoặc một dòng từ một bài hát (ít nhất 20 ký tự)
  • một ngày (hoặc một số khác có sáu chữ số trở lên)
  • số đại lý cá nhân

Trong thực tế, bốn người cuối cùng nên được người gửi và người nhận thỏa thuận trước, bao gồm cả số đại lý của người gửi hoặc người nhận được sử dụng trong mã hóa.

Thông điệp ví dụ của tôi sẽ là: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

Chúng tôi sẽ mã hóa bằng tiếng Anh (mặc dù bạn có thể sử dụng bất kỳ ngôn ngữ và bảng chữ cái nào bạn thích) và các chữ cái phổ biến nhất trong bảng chữ cái tiếng Anh là A, E, I, N, O, R, S, T. Tôi sẽ sử dụng từ khóa SENATORI.

Cụm từ chính của tôi là một câu trích dẫn của Richard Feynman: "Nguyên tắc đầu tiên là bạn không được tự lừa mình - và bạn là người dễ bị lừa nhất".

Như một ngày, tôi sẽ sử dụng ngày 31 tháng 7 năm 2016 (theo định dạng 3172016), đó là ngày tôi viết mô tả này.

Số cá nhân tôi đã chọn cho mình là 9 .

Tóm tắt các bước

  1. Lấy các khóa trung gian để sử dụng trong các bước sau.
  2. Xây dựng và áp dụng các bàn cờ kiểm tra.
  3. Xây dựng và áp dụng bảng chuyển vị đầu tiên.
  4. Xây dựng và áp dụng bảng chuyển vị thứ hai (bị phá vỡ).
  5. Hoàn thiện tin nhắn bằng cách chèn nhóm chỉ báo tin nhắn.

Cơ chế con

Hai điều nữa để giải thích trước khi chúng ta đi vào cốt lõi của vấn đề: các quá trình bổ sung chuỗi và tuần tự hóa.

Ngoài ra chuỗi, còn được gọi là trình tạo Fibonacci bị trễ, hoạt động bằng cách lấy một chuỗi chữ số bắt đầu, thêm hai chữ số đầu tiên mà không mang theo (thêm chúng lại với nhau sau đó mod 10) và nối kết quả vào cuối. Ví dụ:

79081
7 + 9 = 6

790816
9 + 0 = 9

7908169
0 + 8 = 8

79081698
8 + 1 = 9

790816989
1 + 6 = 7

7908169897
... and so on

Tuần tự hóa về cơ bản là lấy một chuỗi các chữ cái hoặc chữ số và ghi nhãn chúng theo thứ tự chữ cái / số. Các bản sao được dán nhãn từ trái sang phải. Ví dụ:

E X A M P L E
    0           # A
1   0       2   # Es
1   0     3 2   # L
1   0 4   3 2   # M
1   0 4 5 3 2   # P
1 6 0 4 5 3 2   # X

3  3  0  5  8  4  2  0  4  7  5  4  8  1
      0              1                     # 0s
      0              1                 2   # 1
      0           3  1                 2   # 2
4  5  0           3  1                 2   # 3s
4  5  0        6  3  1  7        8     2   # 4s
4  5  0  9     6  3  1  7    10  8     2   # 5s
4  5  0  9     6  3  1  7 11 10  8     2   # 7
4  5  0  9 12  6  3  1  7 11 10  8 13  2   # 8s

Tôi sử dụng chỉ mục không ở đây, nhưng chỉ mục theo cách bạn muốn.

1. Khóa trung gian

Chia 20 chữ cái đầu tiên của cụm từ chính thành hai nhóm 10 và tuần tự hóa từng nhóm riêng lẻ, chúng tôi sẽ gọi S1S2.

    THEFIRSTPR
S1: 8201357946

    INCIPLEIST
S2: 2603751489

Chọn một định danh tin nhắn 5 chữ số ngẫu nhiên, M(đây có thể là một trong những đầu vào nếu bạn thích):

M = 47921

Trừ, không vay (trừ mod 10), năm chữ số đầu tiên của ngày chính 3172016từ M:

M      47921
date - 31720
     = 16201

Chuỗi thêm kết quả cho đến khi bạn có mười chữ số:

1620178218

Thêm các chữ số này vào S1, mà không mang hoặc mod 10, để có được G:

     1620178218
S1 + 8201357946
G  = 9821425154

Ở trên S2, viết dãy 0123456789. Xác định vị trí từng chữ số Gtrong dãy 0123456789 và thay thế bằng chữ số ngay bên dưới nó S2. Kết quả là T.

   0123456789
S2 2603751489

G  9821425154
T  9806705657

Sử dụng chuỗi bổ sung để mở rộng Tđến 60 chữ số.

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

50 chữ số cuối cùng này, trong năm hàng mười chữ số mỗi chữ số, tạo thành Ukhối.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Hai chữ số không bằng nhau cuối cùng của Ukhối được thêm riêng vào số cá nhân của tác nhân để đưa ra độ rộng của hai lần chuyển vị pq.

9 + 3 = 12 (p, chiều rộng chuyển vị thứ nhất) 9 + 4 = 13 (q, chiều rộng chuyển vị thứ hai)

Tuần tự hóa Tvà sử dụng chuỗi này để sao chép các cột của Ukhối, từ trên xuống dưới, vào một hàng chữ số mới , V.

T     9806705657
seqT  9804612537

U     7863751124
      5490262369
      9392885958
      2210634430
      4316978734

V     69911 56837 12548 26533 30206 13947 72869 49804 84323 75924

Tuần tự hóa các pchữ số đầu tiên để lấy khóa cho lần hoán vị đầu tiên K1và các qchữ số sau cho khóa thứ hai K2.

First 12  6  9  9  1  1  5  6  8  3  7  1  2
K1        6 10 11  0  1  5  7  9  4  8  2  3

Next 13   5  4  8  2  6  5  3  3  3  0  2  0  6
K2        8  7 12  2 10  9  4  5  6  0  3  1 11

Cuối cùng, tuần tự hóa hàng cuối cùng của Ukhối cần lấy C, các tiêu đề cột cho bảng kiểm tra đóng đai:

U5  4316978734
C   3105968724

2. Bàn cờ

Đầu tiên, tôi sẽ đưa ra bảng kiểm tra ví dụ của mình sau đó giải thích các nguyên tắc trong việc tạo ra nó theo cách đó:

  3 1 0 5 9 6 8 7 2 4
  S E N A T O R I
2 B D G J L P U W Y .
4 C F H K M Q V X Z #

Dòng chữ đầu tiên là từ khóa ngắn của chúng tôi SENATORI. Từ khóa của bạn có thể là bất kỳ chuỗi nào mà không trùng lặp, nhưng vì nó xác định hàng trên cùng của bảng kiểm tra của bạn, hãy chọn một cách khôn ngoan. Phía trên từ khóa là Cvà các hàng khác là phần còn lại của bảng chữ cái của bạn theo bất kỳ thứ tự nào bạn chọn. Trong trường hợp của tôi, tôi điền vào bảng kiểm tra với phần còn lại của bảng chữ cái Latinh, dấu chấm câu .và dấu để phân định số #. Về cơ bản, bàn cờ là một mật mã thay thế lạ mắt. Ví dụ: "E" sẽ được thay thế bằng 1và "W" sẽ được thay thế bằng 27.

Khi chúng tôi đã mã hóa tin nhắn văn bản gốc của mình bằng bảng kiểm tra này, nhưng trước tiên, chúng tôi cần làm cho phần đầu của tin nhắn của chúng tôi ít rõ ràng hơn bằng cách chia nó ở một vị trí ngẫu nhiên và làm cho nó trở thành chữ hoa. Để biểu thị sự khởi đầu ban đầu khác, chúng tôi sử dụng hai điểm dừng đầy đủ..

We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

trở thành

HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT

Chúng tôi mã hóa với bàn cờ, cho chúng tôi:

407020 1293124 496481 96 354114062831 416479869443442424 271 581 
2173436481812124 95451 274059 22628 435024 232880 14818229

Nếu độ dài của tin nhắn không chia hết cho 5, chúng tôi sẽ thêm một số ký tự null để xóa tin nhắn. Tin nhắn của chúng tôi dài 109 chữ số, vì vậy tôi sẽ thêm một null: "4".

40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294

Lưu ý: Vì thông báo ví dụ của tôi không chứa số, tôi sẽ nói ở đây rằng bạn có thể chỉ định, giả sử, #3#được mã hóa như 44344ở đây.

3. Chuyển vị đầu tiên

Tạo bảng chuyển vị bằng cách viết K1(từ phần Khóa trung gian) theo sau là thông báo được mã hóa từ bước trước đó, trong các hàng có cùng độ dài, bên dưới khóa:

K1   6 10 11  0  1  5  7  9  4  8  2  3

     4  0  7  0  2  0  1  2  9  3  1  2
     4  4  9  6  4  8  1  9  6  3  5  4
     1  1  4  0  6  2  8  3  1  4  1  6
     4  7  9  8  6  9  4  4  3  4  4  2
     4  2  4  2  7  1  5  8  1  2  1  7
     3  4  3  6  4  8  1  8  1  2  1  2
     4  9  5  4  5  1  2  7  4  0  5  9
     2  2  6  2  8  4  3  5  0  2  4  2
     3  2  8  8  0  1  4  8  1  8  2  2
     9  4

Lấy các cột được đánh số theo thứ tự số của chúng tôi nhận được:

060826428  246674580  151411542  246272922  961311401  082918141
4414434239 118451234  334422028  293488758  0417249224 794943568

4. Chuyển vị thứ hai

Sự hoán vị đầu tiên tương đối đơn giản. Điều này, tuy nhiên, là một chuyển vị bị gián đoạn. Mẫu phá vỡ được xác định bởi chiều rộng của bảng và khóa. Trong ví dụ của chúng tôi, chúng tôi có 110 chữ số và 13 cột, nghĩa là chúng tôi sẽ có 8 hàng đầy đủ và 6 hàng thừa. Chúng tôi bắt đầu điền vào hàng đầu tiên, nhưng dừng lại ở cột 0 và tiếp tục như sau:

K2   8  7 12  2 10  9  4  5  6  0  3  1 11

     0  6  0  8  2  6  4  2  8              stop at 0
     2  4  6  6  7  4  5  8  0  1           continue in a triangle pattern
     5  1  4  1  1  5  4  2  2  4  6
     2  7  2  9  2  2  9  6  1  3  1  1
     4  0  1  0  8  2  9  1  8  1  4  1  4  until the end
     4  1  4  4  3  4  2  3  9  1  1        restart and stop at 1
     8  4  5  1  2  3  4  3  3  4  4  2
     2  0  2  8  2  9  3  4  8  8  7  5  8
     0  4  1                                restart and stop at 2

Sau đó, chúng tôi điền vào vài chỗ trống cuối cùng với các chữ số còn lại.

K2   8  7 12  2 10  9  4  5  6  0  3  1 11

     0  6  0  8  2  6  4  2  8  7  2  4  9
     2  4  6  6  7  4  5  8  0  1  2  2  4
     5  1  4  1  1  5  4  2  2  4  6  7  9
     2  7  2  9  2  2  9  6  1  3  1  1  4
     4  0  1  0  8  2  9  1  8  1  4  1  4
     4  1  4  4  3  4  2  3  9  1  1  9  4
     8  4  5  1  2  3  4  3  3  4  4  2  3
     2  0  2  8  2  9  3  4  8  8  7  5  8
     0  4  1  5  6  8

Bây giờ, chúng tôi đọc các cột theo chính xác như cách chúng tôi đã làm trong lần chuyển vị đầu tiên.

71431148  42711925  861904185 22614147  45499243  28261334  80218938
641701404 025244820 645224398 271283226 94944438  064214521

Và chia mọi thứ thành các nhóm 5 chữ số:

71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521

5. Hoàn tất tin nhắn

Bước cuối cùng là chèn định danh tin nhắn ngẫu nhiên của chúng tôi 47921vào chính thông điệp. Chữ số cuối cùng của ngày chính 6cho biết khoảng cách nhóm nên đi từ cuối.

71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521

Ghi chú cho thử thách này

  • Bạn được cung cấp tối thiểu năm đầu vào: tin nhắn, từ khóa chữ cái, cụm từ chính, ngày tháng và số cá nhân. Bạn có thể bao gồm hai đầu vào bổ sung: số nhận dạng thông báo ngẫu nhiên và null cần thiết để xóa tin nhắn hoặc chức năng của bạn có thể tự tạo một số số ngẫu nhiên.
  • Bạn có thể giả sử tất cả các đầu vào là hợp lệ, với số chữ số và chữ cái chính xác (số nhận dạng tin nhắn 5 chữ số, ít nhất 20 chữ số cho cụm từ khóa, v.v.). Bạn có thể cho rằng các chuỗi của bạn (tin nhắn và từ khóa) đã bị xóa hết dấu chấm câu và dấu cách trừ các chuỗi bạn cho phép trong phiên bản của mình và các số đó đã được phân định bằng ký hiệu số.
  • Từ khóa đầu tiên không nên có các chữ cái trùng lặp trong đó và trong mã của bạn, bạn có thể cho rằng nó không bao giờ có các chữ cái trùng lặp.
  • Ngôn ngữ bạn sử dụng để mã hóa không thành vấn đề, miễn là ngôn ngữ đó có từ trước, bảng chữ cái có từ trước và bạn chỉ định ngôn ngữ nào bạn sử dụng trong câu trả lời của mình.
  • Bất cứ bảng chữ cái nào bạn sử dụng cho bàn cờ của bạn, bạn có thể thêm hoặc xóa các ký hiệu để bỏ bảng kiểm tra ra. Chỉ định những gì bạn sử dụng các ký hiệu đó cho (ví dụ: dấu chấm câu, ký hiệu "thông điệp bắt đầu" riêng biệt, ký hiệu cho các từ phổ biến). Bạn có thể từ bỏ hoàn toàn ký hiệu số và đánh vần các số hoặc bao gồm từng chữ số trong bảng kiểm tra, sử dụng vị trí có ký hiệu số cho một số khác. Vui lòng chỉ định bảng kiểm tra bạn đã sử dụng trong câu trả lời của bạn.
  • Đầu ra phải là một chuỗi các nhóm năm chữ số được phân tách bằng dấu cách, một danh sách các số nguyên năm chữ số hoặc một cái gì đó tương tự.
  • Tôi đã sử dụng chỉ mục không và 0123456789trong ví dụ của tôi. Bạn có thể sử dụng lập chỉ mục 1 và 1234567890, hoặc một số hệ thống khác trong câu trả lời của bạn, miễn là bạn chỉ định những gì bạn đã sử dụng.

Dưới đây là một ví dụ thực hiện trên Ideone .

Đây là một bài viết dài và tôi đã viết hầu hết bằng tay, vì vậy nếu có bất kỳ phần khó hiểu nào trong bài đăng này hoặc lỗi trong việc đếm và chuyển đổi của tôi, xin vui lòng cho tôi biết. Chúc may mắn và chơi golf tốt!


1
adding the first two digits without addingBạn có nghĩa là mang?
isaacg

@isaacg Vâng, tôi đã làm. Đã chỉnh sửa.
Sherlock9

Bạn có thể làm rõ những gì bạn có nghĩa là without borrowingwithout carrying? Bạn có nghĩa là cộng và trừ mod 10, tức là (6+7) mod 10 = 3(6-8) mod 10 = 8?
R. Kap

@ R.Kap Vâng, hãy để tôi làm rõ điều đó.
Sherlock9

Chúng ta phải phân định số?
R. Kap

Câu trả lời:


10

Python 3 , 1423 1348 1324 1316 1300 1286 1250 1249 1209 1206 1204 byte

Đây chắc chắn là sân golf dài nhất tôi từng làm và là sân golf duy nhất mà tôi lo lắng nghiêm trọng về việc hết tên biến một ký tự. Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

Tôi đang mã hóa bằng bảng chữ cái Latinh viết hoa với các ký tự bổ sung .#, sử dụng lập chỉ mục 0 và 0123456789khi chuyển đổi gsang t. Bảng kiểm tra của tôi có định dạng tương tự như ví dụ sau:

  2 9 7 4 5 8 3 1 0 6    # C
  S E N A T O R I        # keyword
0 B D G J L P U W Y .    # remaining alphabet arranged in columns
6 C F H K M Q V X Z #    # . and # at the end

Chỉnh sửa: -63 byte nhờ đề xuất của TuukkaX để rút ngắn một số hàm thường được sử dụng với các biến một chữ cái. -12 byte từ việc tạoa, g, t gọn hơn.

Chỉnh sửa: -24 byte từ việc tạo bằng cách xóa tên biến cho các khóa trung gian chỉ được sử dụng một lần, cụ thể là a, g, s, S, k, K.

Chỉnh sửa: -74 byte từ hợp nhất H(), T() and C().

Chỉnh sửa: -1 byte nhờ Nick A cho đề xuất thay đổi ord(s[i])+ord(s[i+1])thành sum(map(ord,s[i:i+2])). -2 byte từ việc thay đổi 2 +=[a]cuộc gọi đến +=a,. -13 byte từ việc thay đổi cách G()tìm thấy chỉ số tối thiểu s. -2 byte từ thay đổi y=(y+1)%vthành y=-~y%v. -15 byte từ việc gán k.index()cho K. -4 byte từ việc gán 10cho W. -5 byte từ gán 1-I(d[-1])vào Xbên trong V. -3 byte từ việc viết lại C()vòng lặp chính. -2 byte từ sắp xếp lại T().

I=int;L=list;E=len;R=range;B=str;J=''.join;W=10
def H(s,e):
 for i in R(e-E(s)):s+=chr(48+sum(map(ord,s[i:i+2]))%32%W)
 return s
def Q(s):
 r=[0]*E(s);s=L(s)
 for z in R(E(s)):b=s.index(min(s));r[b]=z;s[b]="~"
 return r
def T(x,k,d=0):
 u=E(x);v=E(k);g=R(v);K=k.index;n=u//v+1;w=[];e=r=y=0;i=K(y);c=[]
 if d:
  while r<n:
   if r>n-1:i=min(i,(u%v or v))
   w+=L(x[e:e+i]),;e+=i;i+=1;r+=1
   if i>v:y=-~y%v;i=K(y)
  r=y=0;i=v-K(y)
  while r<n:
   w[r]+=L(x[e:e+i]);e+=i;i-=1;r+=1
   if i<1:y+=1;i+=v-K(y);r+=1
  w[-1]+=['']*(v-E(w[-1]))
  for j in g:c+=J(z[j]for z in w),
 else:c=[x[i::v]for i in g]
 s=[0]*v
 for f in g:s[k[f]]=c[f]
 return J(s)
def C(m,s,w,n):
 t={".":s[-2:],"#":s[-1]*2};j=z=0
 for x in R(26):
  v=chr(x+65)
  if v in w:t[v]=s[w.index(v)]
  else:t[v]=s[z-2]+s[j];j+=z;z=-~z%2
 r=J(i.isdigit()and i or t[i]for i in m)
 return r+n[:-E(r)%5]
def V(m,w,P,d,A,M,n):X=1-I(d[-1]);t=J(B(Q(P[W:20])[I(J(B((I(H(J(B((I(M[i])-I(d[i]))%W)for i in R(5)),W)[i])+I(Q(P[:W])[i]))%W)for i in R(W))[i])])for i in R(W));u=H(t,60)[W:];p=A+I(u[-2]);v=T(u,Q(t));z=T(T(C(m,J(B(i)for i in Q(u[40:])),w,n),Q(v[:p])),Q(v[p:p+A+I(u[-1])]),1);e=[z[5*i:5*-~i]for i in R(-(-E(z)//5))];return' '.join(e[:X]+[M]+e[X:])

Ungolfing:

def chain_add(seq, end):
    for i in range(end - len(seq)):
        seq += chr(48+sum(map(ord,seq[i:i+2]))%32%10)
    return seq

def sequent(seq):
    res = [0]*len(seq)
    seq = list(seq)
    for z in range(len(seq)):
        b = seq.index(min(seq))
        res[b] = z
        seq[b] = "~"
    return res

def transpose(text, keys, disrupt=False):
    if disrupt:
        num_rows = len(text) // len(keys) + 1
        len_last = len(text) % len(keys)
        if len_last == 0:
            len_last = len(keys)
        d_rows = []
        text_index = 0
        current_row = 0
        stop_key = 0
        stop_index = keys.index(stop_key)
        while current_row < num_rows:
            if current_row > num_rows-1:
                stop_index = min(stop_index, len_last)
            d_rows += [list(text[text_index:text_index+stop_index])]
            text_index += stop_index
            stop_index += 1
            if stop_index>len(keys):
                stop_key = (stop_key+1) % len(keys)
                stop_index = keys.index(stop_key)
            current_row += 1
        current_row = 0
        stop_key = 0
        stop_len = len(keys) - keys.index(stop_key)
        while current_row < num_rows:
            d_rows[current_row] += list(text[text_index:text_index+stop_len])
            text_index += stop_len
            stop_len -= 1
            if stop_len < 1:
                stop_key += 1
                stop_len = len(keys) - keys.index(stop_key)
                current_row += 1
            current_row += 1
        d_rows[-1] += ['']*(len(keys)-len(d_rows[-1]))
        columns = []
        for j in range(len(keys)):
            columns += [''.join(i[j]for i in d_rows)]
    else:
        columns = ['']*len(keys)
        for t in range(len(text)):
            columns[t%len(keys)] += text[t]
    res = [0]*len(keys)
    for index in range(len(keys)):
        res[keys[index]] = columns[index]
    return''.join(res)

def checkerboard(message, seq, word, null):
    trans = {".":seq[-2:], "#":seq[-1]*2};res='';j=z=0
    for x in range(26):
        v = chr(x + 65)
        if v in word:
            trans[v] = seq[word.index(v)]
        else:
            trans[v] = seq[z-2] + seq[j]
            j += z
            z = (z+1) % 2
    for i in message:
        if i.isdigit():
            res += i
        else:
            res += trans[i]
    return res + null[:-len(res)%5]

def vic_cipher(message, keyword, phrase, date, agent, m_id, null):
    s1 = sequent(phrase[:10])
    s2 = sequent(phrase[10:20])
    a = ''.join(str((int(m_id[i])-int(date[i]))%10) for i in range(5))
    g = ''.join(str((int(a[i])+int(s1[i]))%10) for i in range(10))
    t = ''.join(str(s2[int(g[i])]) for i in range(10))
    u = chain_add(t,60)[10:]
    p = agent+int(u[-2])
    q = agent+int(u[-1])
    seqT = sequent(t)
    v = transpose(u,seqT)
    k1 = sequent(v[:p])
    k2 = sequent(v[p:p+q])
    c = ''.join(str(i)for i in sequent(u[40:]))
    x = checkerboard(message,c,keyword,null)
    y = transpose(x,k1)
    z = transpose(y,k2,1)
    e = [z[5*i:5*(i+1)] for i in range(-(-len(z)//5))]
    X = 1-int(date[-1])
    return ' '.join(e[:X] + [m_id] + e[X:])

2
Python 3 cho phép các ký tự unicode là biến, FYI.
Paul

Thay đổi ord(seq[i])+ord(seq[i+1])để sum(map(ord,seq[i:i+2]))tiết kiệm 1 ký tự tôi tin.

3

C, 2880 2769 2766 2762 2743 2741 2739 2699 2458 byte

#include<stdio.h>
#define m(x)malloc(x)
#define Y(x)strlen(x)
typedef int i;typedef char*c;c _(c A,i B,i D){if(D>=B){return A;}c C=m(Y(A)+2);sprintf(C,"%s%c",A,48+(A[D]+A[D+1]-96)%10);return _(C,B,D+1);}c l(c A){i J=Y(A);c P=m(J+2);for(i m=0;m<J;m++){P[m]=32;}for(i v=0;v<J;v++){char G;i R;for(i u=0;u<J;u++){R=u<1|A[u]<G?u:R;G=u<1|A[u]<G?A[u]:G;}P[R]=48+v;c V=m(J);for(i t=0;t<J;t++){V[t]=t!=R?A[t]:97;}A=V;}return P;}c S(c C,c N,c I,char U){srand(time(NULL));i M=Y(I);i O=Y(N);i R=rand()%M;c Q=m(M+1);for(i u=R;u<M;u++){Q[u-R]=I[u];}Q[M-R]=46;for(i H=0;H<R;H++){Q[H+M-R+1]=I[H];}c g=m(28);c V=m(28);strcat(V,C);sprintf(g,"%s%s",N,"BCDFGHJKLMPQUVWXYZ.#");i B=Y(N);for(i q=B;q<10;q++){for(i x=0;x<10;x++){char J[2]={C[q],C[x]};V[B]=48+atoi(J);B++;}}c w=m(M*2+4);for(i J=0;J<=M;J++){i K=0;for(i X=0;X<28;X++){if(Q[J]==g[X]){char F[3];sprintf(F,"%d",V[X]-48);strcat(w,F);K=1;}}if(K<1){w[Y(w)]=Q[J];}}i f=Y(w);if(f%5>0){c P=m(5-f%5);for(i E=0;E<5-f%5;E++){P[E]=U;}strcat(w,P);}return w;}c a(c I,c U){i M=Y(I),K=Y(U);c T=m(M);i F=0;for(i b=0;b<K;b++){for(i y=0;y<K;y++){if(U[y]==48+b){for(i u=y;u<M;u+=K){T[F]=I[u];F++;}}}}return T;}c da(c I,c K){i e=Y(I),k=Y(K);c T=m(e);for(i y=0;y<e;y++){T[y]=32;}i F,P;F=P=0;for(i u=0;u<k;u++){for(i v=0;v<k;v++){T[F]=I[P];P++;F++;if(K[v+1]-48==u){for(i C=1;C<k-v;C++){F+=k-v-C;for(i E=0;E<=v+C;E++){if(F<e&P<e){T[F]=I[P];}F++;P++;}}break;}}if(F>e){break;}}i U=0;for(i g=0;g<e;g++){U=T[g]-48<10&-1<T[g]-48?U+1:U;}for(i j=U;j<e;j++){for(i x=0;x<e;x++){if(T[x]==32){T[x]=I[j];break;}}}return a(T,K);}En(c n,c m,c k,i d,c v,c s,char u){c S1,S2;S1=m(10);S2=m(10);for(i i=0;i<20;i++){if(i<10){S1[i]=k[i];}else{S2[i-10]=k[i];}}S1=l(S1);S2=l(S2);c M=m(5);for(i i=4;i>-1;i--){M[i]=48+(s[i]-v[i])%10;}c G=_(M,5,0);for(i y=0;y<10;y++){G[y]=48+(S1[y]+G[y]-96)%10;}c N="0123456789";c T=m(10);for(i q=0;q<10;q++){for(i t=0;t<10;t++){if(N[t]==G[q]){T[q]=S2[t];}}}c Z=_(T,50,0);c U=m(50);for(i h=0;h<50;h++){U[h]=Z[h+10];}i p,q;for(i b=49;b>10;b++){if(U[b]!=U[b-1]){q=d+U[b]-48;p=d+U[b-1]-48;break;}}c V=m(50);i Ct=0;for(i j=0;j<10;j++){for(i o=0;o<10;o++){if(l(T)[o]==48+j){for(i x=o;x<o+41;x+=10){V[Ct]=U[x];Ct+=1;}}}}c K1=m(p);c K2=m(q);for(i D=0;D<p+q;D++){if(D<p){K1[D]=V[D];}else{K2[D-p]=V[D];}}K1=l(K1);K2=l(K2);c C=m(10);for(i b=40;b<50;b++){C[b-40]=U[b];}C=l(C);c t=da(a(S(C,m,n,u),K1),K2);i O=0;for(i B=0;B<Y(t)/5+1;B++){if(B==Y(t)/5-v[Y(v)-1]+49){printf("%s ",s);}else{for(i J=O;J<O+5;J++){printf("%c",t[J]);}printf(" ");O+=5;}}}

Trời ơi. Đây là chương trình dài nhất tôi từng có để chơi golf. Đây cũng là lần đầu tiên tôi thực sự hết tên biến một ký tự cho phạm vi toàn cầu và do đó phải chuyển sang sử dụng một vài ký tự 2 (thực tế là tôi rõ ràng không thể xác định lại các biến không giúp ích). Lời khuyên chơi golf vì thế được đánh giá rất cao.

Ung dung

Biên dịch mà không có bất kỳ cảnh báo, không giống như phiên bản golf. Những thay đổi nhỏ được thực hiện cho phiên bản chơi gôn sẽ không được phản ánh trong phiên bản không được chỉnh sửa này.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char*Chain_Add(char*String,int End,int Start){
  if(Start>=End){return String;}
  char*C=malloc(strlen(String)+2);
  sprintf(C,"%s%c",String,'0'+(((String[Start]-'0')+(String[Start+1]-'0'))%10));
  return Chain_Add(C,End,Start+1);
}

char*Sequent(char*String){
  int J=strlen(String);
  char*P=malloc(J+2);
  for(int m=0;m<J;m++){
    P[m]=' ';
  }
  for(int v=0;v<J;v++){
    char G;
    int R;
    for(int u=0;u<J;u++){
      R=(u<1||String[u]<G)?u:R;
      G=(u<1||String[u]<G)?String[u]:G;
    }
    P[R]='0'+v;
    char*V=malloc(J);
    for(int t=0;t<J;t++){
      if(t!=R){
    V[t]=String[t];
      }
      else{
    V[t]='a';
      }
    }
    String=V;
  }
  return P;
}

char*Straddling_Checkerboard(char*C,char*Key,char*Message,char null){
  srand(time(NULL));
  int Msg_Len=strlen(Message);
  int Key_Len=strlen(Key);
  int R=rand()%Msg_Len;
  char*Q=malloc(Msg_Len+1);
  for(int u=R;u<Msg_Len;u++){
    Q[u-R]=Message[u];
  }
  Q[Msg_Len-R]='.';
  for(int H=0;H<R;H++){
    Q[H+Msg_Len-R+1]=Message[H];
  }
  char*Alphabet=malloc(26);
  for(int W=0;W<26;W++){
    Alphabet[W]='A'+W;
  }
  int q=0;
  char*e=malloc(Key_Len);
  for(int z=0;z<Key_Len;z++){
    if(strchr(e,Key[z])!=NULL){
      q++;
    }
    else{
      e[z-q]=Key[z];
    }
  }
  int r=0;
  for(int h=0;h<26;h++){
    if(strchr(e,Alphabet[h-r])!=NULL){
      for(int X=h-r;X<26;X++){
    Alphabet[X]=Alphabet[X+1];
      }
      r++;
    }
  }
  char*Checkerboard=malloc(28);
  for(int i=0;i<26;i++){
    if(i<strlen(e)){
      Checkerboard[i]=e[i];
    }
    else{
      Checkerboard[i]=Alphabet[i-strlen(e)];
    }
  }
  Checkerboard[26]='.';
  Checkerboard[27]='#';
  char*Values=malloc(28);
  strcat(Values,C);
  int B=strlen(e);
  for(int q=B;q<10;q++){
    for(int x=0;x<10;x++){
      char J[2]={C[q],C[x]};
      Values[B]='0'+atoi(J);
      B++;
    }
  }
  char*Encoded=malloc(Msg_Len*2+4);
  for(int J=0;J<=Msg_Len;J++){
    int K=0;
    for(int X=0;X<28;X++){
      if(Q[J]==Checkerboard[X]){
    char F[3];
    sprintf(F,"%d",Values[X]-'0');
    strcat(Encoded,F);
    //printf("F = %s while Q[J] = %c and Checkerboard[X] = %c and Encoded = %s\n",F,Q[J],Checkerboard[X],Encoded);
    K=1;
      } 
    }
    if(K<1){
      Encoded[strlen(Encoded)]=Q[J];
    }
  }
  int Encded_Len=strlen(Encoded);
  if(Encded_Len%5>0){
    char*P=malloc(5-Encded_Len%5);
    for(int E=0;E<5-Encded_Len%5;E++){
      P[E]=null;
    }
  strcat(Encoded,P);
  }
  return Encoded;
}

char*Transpose(char*Message,char*K1){
  int Msg_Len=strlen(Message),K1_Len=strlen(K1);
  char*T=malloc(Msg_Len);
  int F=0;
  for(int i=0;i<K1_Len;i++){
    for(int y=0;y<K1_Len;y++){
      if(K1[y]=='0'+i){
    for(int u=y;u<Msg_Len;u+=K1_Len){
      T[F]=Message[u];
      F++;
    }
      }
    }
  }
  return T;
}

char*Disrupted_Transpose(char*Message,char*K2){
  int Msg_Len=strlen(Message),K2_Len=strlen(K2);
  char*T=malloc(Msg_Len);
  for(int y=0;y<Msg_Len;y++){
    T[y]=' ';
  }
  int F=0;
  int P=0;
  for(int u=0;u<K2_Len;u++){
    for(int v=0;v<K2_Len;v++){
      T[F]=Message[P];
      P++;F++;
      if(K2[v+1]-'0'==u){
        for(int C=1;C<K2_Len-v;C++){
      F+=K2_Len-v-C;
      for(int E=0;E<=v+C;E++){
        if(F<Msg_Len&P<Msg_Len){
          T[F]=Message[P];
        }
        F++;P++;
      }
    }
    break;
      }
    }
    if(F>Msg_Len){
      break;
    }
  }
  int U=0;
  for(int g=0;g<Msg_Len;g++){
    U=(T[g]-'0'<10&-1<T[g]-'0')?U+1:U;
  }
  for(int j=U;j<Msg_Len;j++){
    for(int x=0;x<Msg_Len;x++){
      if(T[x]==' '){
    T[x]=Message[j];
    break;
      }
    }
  }
  return Transpose(T,K2);
}

void VIC_Encoder(char*Message,char*Phrase,char*Key,int a_id,char*date,char*m_id,char null){
  char*S1=malloc(10);
  char*S2=malloc(10);
  for(int i=0;i<20;i++){
    if(i<10){
      S1[i]=Key[i];
    }
    else{
      S2[i-10]=Key[i];
    }
  }
  S1=Sequent(S1);
  S2=Sequent(S2);
  char*M=malloc(5);
  for(int i=4;i>-1;i--){
    M[i]='0'+(((m_id[i]-'0')-(date[i]-'0'))%10);
  }
  char*G=Chain_Add(M,5,0);
  for(int y=0;y<10;y++){
    G[y]='0'+(((S1[y]-'0')+(G[y]-'0'))%10);
  }
  char*N="0123456789";
  char*T=malloc(10);
  for(int q=0;q<10;q++){
    for(int t=0;t<10;t++){
      if(N[t]==G[q]){
    T[q]=S2[t];
      }
    }
  }
  char*Z=Chain_Add(T,50,0);
  char*U=malloc(50);
  for(int h=0;h<50;h++){
    U[h]=Z[h+10];
  }
  int p,q;
  for(int b=49;b>10;b++){
    if(U[b]!=U[b-1]){
      q=a_id+(U[b]-'0');
      p=a_id+(U[b-1]-'0');
      break;
    }
  }
  char*seqT=Sequent(T);
  char*V=malloc(50);
  int Count=0;
  for(int j=0;j<10;j++){
    for(int o=0;o<10;o++){
      if(seqT[o]=='0'+j){
    for(int x=o;x<o+41;x+=10){
      V[Count]=U[x];
      Count+=1;
    }
      }
    }
  }
  char*K1=malloc(p);
  char*K2=malloc(q);
  for(int D=0;D<p+q;D++){
    if(D<p){
      K1[D]=V[D];
    }
    else{
      K2[D-p]=V[D];
    }
  }
  K1=Sequent(K1);
  K2=Sequent(K2);
  char*C=malloc(10);
  for(int b=40;b<50;b++){
    C[b-40]=U[b];
  }
  C=Sequent(C);
  char*Transposed_2=Disrupted_Transpose(Transpose(Straddling_Checkerboard(C,Phrase,Message,null),K1),K2);
  int O=0;
  for(int B=0;B<strlen(Transposed_2)/5+1;B++){
    if(B==strlen(Transposed_2)/5-date[strlen(date)-1]+'1'){
      printf("%s ",m_id);
    }
    else{
      for(int J=O;J<O+5;J++){
    printf("%c",Transposed_2[J]);
      }
      printf(" ");
      O+=5;
    }
  }
}

Ghi chú

  • Cái này sử dụng một bàn cờ tương tự như sau để mã hóa tin nhắn:

      3 4 5 6 2 3 4 5 6 7
      S E N A T O R I     
    6 B C D F G H J K L M 
    7 P Q U V W X Y Z . #
    
  • Điều này giả định rằng tất cả các chuỗi áp dụng được đưa ra bằng chữ in hoa. Thông báo cũng phải có tất cả dấu chấm trừ các dấu chấm được xóa và tất cả các số được phân định bởi #s, trong khi cụm từ chính phải xóa tất cả dấu chấm câu.

  • Thông báo được mã hóa kết quả là đầu ra cho STDOUT dưới dạng một chuỗi các nhóm năm chữ số được phân tách bằng dấu cách.

  • Thông điệp đầu vào phải bằng tiếng Anh.

  • Tôi đã kết hợp một vài hàm tôi đã sử dụng, nhưng sau đó tôi sẽ phải sử dụng nhiều tên biến có hai chữ cái hơn, làm cho chương trình cuối cùng dài hơn so với một vài hàm khác.

  • Điều này hiện tại không cho rằng từ khóa (ít nhất là bằng tiếng Anh) sẽ luôn chứa cùng một bộ chữ cái, và do đó bù lại bằng cách loại bỏ trùng lặp, thao tác với bàn cờ, v.v. Khả năng này rõ ràng là không bắt buộc bởi OP, Vì vậy, tôi hiện đang chơi golf thêm các byte không cần thiết đang chiếm. Cập nhật cho phiên bản golf.


2

JavaScript (ES6), 946 938 953 byte

V=(c,d,f,g,j,k,m)=>{S=a=>a.split``,J=a=>a.join``,A=(a,b)=>{for(i=0;a[L="length"]<b;a+=(a[i++]- -a[i])%h);return a},Q=b=>(a=S(b).sort(),S(b).map(b=>a[i=a[X="indexOf"](b)]=i)),u=A(t=J(S(A(J(S(k).map((a,b)=>Math.abs(a-g[b]))),h=10)).map((a,b)=>Q(f[C="slice"](h,20))[(Q(f[C](0,h))[b]- -a)%h])),60)[C](h),T=((a,b,c)=>{if(r=Array(l=b[L]).fill(""),c){for(e=a[L]/l,i=0,w=[],u=R=b[X](x=0);i<e;)w[i++]=a[P](0,R++),u?u=0:R>l||(R=b[X](u=++x));for(i=0;i<e;)w[i]=J(w[i].concat(a[P](0,l-w[i++][L])));a=J(w)}for(i in a)r[+b[i%l]]+=a[i];return r}),v=J(T(u,Q(t))),q=J(Q(u[C](-h))),t="ABCDEFGHIJKLMNOPQRSTUVWXYZ#".match(new RegExp("[^"+d+"]","g")),t[P="splice"](9,0,"."),M=[];for(i in t)M[t[i]]=q[8^i/h]+(M[d[i]]=q[i%h]);for(n=c[L],b=J((c[C](n-=new Date%n)+"."+c[C](0,n)).split(/ |/).map(a=>M[a]||a)),b+=m.repeat(5-b[L]%5),i=f=q=49;f==q;)f=+u[i-1]+j,q=+u[i++]+j;return t=J(T(S(J(T(b,Q(v[C](0,f))))),Q(v.substr(f,q)),1)).match(/.{5}/g),g=-g[C](-1),g++&&t[P](g||t[L],0,k),t}

Tôi đã thấy cuối tuần qua không có mục nhập nào cho việc này, vì vậy đây là nỗ lực (phút cuối) của tôi. Thực hiện và chơi golf này là điên rồ như nó là niềm vui!

Đoạn giới thiệu

Chỉnh sửa: -8 byte

Nhận ra có thêm dấu ngoặc đơn xung quanh chức năng S,J,A,Q

Chỉnh sửa: +15 byte

Đã cập nhật logic cho cách message idđặt trong thông báo cuối cùng (hiện có 1 chỉ mục và 0 không bao gồm nó trong đầu ra).

Ung dung

chainAdd = (s,l)=>{for(i=0;s.length<l;s+=(s[i++]- -s[i])%10);return s;}

sequentialize = (s)=> {
    a=s.split('').sort();
    return s.split('').map(c=>(i=a.indexOf(c),a[i]='',i));  
}

transpose = (s,k,disruptive)=>{
    var result=Array(k.length).fill('')
    if(disruptive){
        rows=[]
        k_index=0;
        rowLength=k.indexOf(k_index);
        triangling=!rowLength;

        expectedRows = s.length/k.length
        for(row=0;row<expectedRows;row++){
            rows[row]=s.splice(0,rowLength++)
            if(triangling){     
                if(rowLength>k.length){
                    triangling=false;
                    rowLength=k.indexOf(++k_index)              
                }
            }
            else{               
                triangling=true;
            }
        }

        for(row=0;row<expectedRows;row++){
            rows[row]= rows[row].concat(s.splice(0,k.length-rows[row].length)).join('')
        }
        s=rows.join('')
    }
    for(i in s)
        result[+k[i%k.length]]+=s[i];   
    return result;
}

checkerboard =(message,seq, keyword, nulls)=>{  
    t='ABCDEFGHIJKLMNOPQRSTUVWXYZ#'.match(new RegExp('[^'+keyword+']','g'));
    t.splice(9,0,'.')

    map=[]
    for(i in t)
        map[t[i]]=(seq[8^(i/10)])+(map[keyword[i]]=seq[i%10])

    r = new Date%message.length;
    rotateMessage=message.substr(message.length-r)+'.'+message.substr(0,message.length-r)

    result =rotateMessage.split(/ |/).map(x=>map[x]||x).join('');
    result+=nulls.repeat(5-result.length%5)

    return result;
}

vic = (message, keyword, phrase, date, agent, m_id, nulls)=>{
    s1=sequentialize(phrase.substr(0,10))//.join('')
    s2=sequentialize(phrase.substr(10,10))//.join('')

    r = m_id.split('').map((x,i)=>Math.abs(x-date[i])).join('')
    g = chainAdd(r,10).split('').map((x,i)=>(s1[i]- -x)%10);

    t = g.map(i=>s2[+i]).join('');
    u=chainAdd(t,60).substr(10)

    var p,q;
    for(i=49;p==q;i++){
        p=agent + +u[i-1];
        q=agent + +u[i];
    }
    seqT = sequentialize(t);
    v=transpose(u,seqT).join('');

    k1 = sequentialize(v.substr(0,p));
    k2 = sequentialize(v.substr(p,q));
    c  = sequentialize(u.substr(-10)).join('')

    CB =checkerboard(message,c, keyword, nulls);
    t1=transpose(CB,k1).join('')
    t2=transpose(t1.split(''),k2,1).join('').match(/.{5}/g);
    (d=-date.substr(-1))&&t2.splice((d+1)||t2.length,0,m_id);
    return t2;
}

Ghi chú

  • Cái này sử dụng một bàn cờ tương tự như sau để mã hóa tin nhắn:

      3 1 0 5 9 6 8 7 2 4
      S E N A T O R I
    2 B C D F G H J K L .
    4 M P Q U V W X Y Z #
    
  • Tất cả các chuỗi được đưa ra bằng chữ hoa. Thông báo là chữ Latinh chữ và số (cộng .#) và nên xóa tất cả dấu câu (trừ dấu chấm). Tất cả các số phải được đánh dấu bằng #s. Các cụm từ chính nên loại bỏ tất cả dấu chấm câu / dấu cách.

  • Thông báo kết quả được trả về dưới dạng một mảng gồm 5 chuỗi chữ số.

Cải tiến

  • Tôi cảm thấy như có một cách để lạm dụng "Tất cả các ngôn ngữ" để lưu một số byte. Nếu tôi có nhiều thời gian hơn, tôi sẽ cấu hình lại điều này để cho rằng ngôn ngữ giống như tiếng Hawaii chỉ có 12 chữ cái.

  • Bất kỳ đề nghị chơi golf luôn được chào đón.


Bạn có thể vui lòng thêm một đoạn để tôi có thể xác minh rằng điều này hoạt động không? Nếu vậy, tôi có thể thưởng cho bạn tiền thưởng.
R. Kap

@ R.Kap Chắc chắn, tôi đã thêm một đoạn demo
SLuck49

Hmm ... trong bản demo, message identifierdường như 7cách xa kết thúc thay vì 6. Ngoài ra, trong phiên bản không được phép của bạn, điều tương tự Iddường như 6cách xa từ đầu thay vì kết thúc.
R. Kap

@ R.Kap Vâng, có một lỗi khi tôi đăng nó lần đầu tiên (không được sửa nó trong phần chưa được chỉnh sửa). Đối với môn đánh gôn, tôi cho rằng đó là chỉ số 0 bởi vì nếu không thì 1có nghĩa là cuối cùng bạn sẽ nói message identifiernên đi đâu 0? Tôi có thể thay đổi nó tôi chỉ cần biết.
SLuck49

Tôi có thể nói rằng trên 0các message identifiernên được bỏ qua từ đầu ra.
R. Kap

1

Clojure, 1197 1212 byte

Ôi, tôi kiệt sức rồi.

Cập nhật: Đã thêm vị trí chia ngẫu nhiên cần thiết của tin nhắn, phiên bản không được sử dụng cùng vị trí với ví dụ đã cho để thuật toán có thể được xác minh dễ dàng.

(defn enc[I K E D Y M](let[P split-at A concat Z zipmap R partition W mapcat % count X repeat O vector / map x(fn[C](apply / O C))G range t 10 r(G t)m(fn[i](mod i t))F(fn[[n & N]](/ last(iterate(fn[[[b & N]a]][(A N[(m(+ a b))])b])[N n])))Q(fn[S](for[i(G(% S))a[(nth S i)]](apply +(%(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))[S J](/ Q(P t(take 20 E)))T(/(Z r J)(/ m(/ + S(F(/ - M D)))))U(take 50(drop t(F T)))l(last U)p(+ Y(last(remove #{l}U)))V(W(Z(Q T)(x(R t U)))r)[k j](/ Q(P p(take(+ p Y l)V)))B(into(Z(/ char(G 48 58))(G))(/(fn[i c][c(+(*(quot i 10)20)(nth(Q(reverse(take t(reverse U))))(m i)))])(G)(A(str K",,")(remove(set K)(/ char(A(G 65 91)".#"))))))?(% k)T(vec(filter some?(W(Z k(x(R ?(A(flatten(R 5(A(W str(/ B(let[[b e](P(rand-int(count I))I)](apply str(A e".. "b)))))(X 4(B\,)))))(X(dec ?)nil)))))(G ?))))w (% j)NR(+(quot(% T)w)1)L(flatten(for[k r](for[i(G(.indexOf j k)(inc w))](G i))))C(for[[r c](/ O(rest(reductions + -1(/(fn[i](get{0 1}i 0))L)))L):when(< r NR)][r c])H(R 5(filter some?(W(Z j(x(R w (A(vals(into(sorted-map)(/ O(A C(for[i(G NR)j(G w)c[[i j]]:when(not((set C)c))]c))T)))(X(dec w)nil)))))(G w))))](/(fn[p](apply str p))(let[[b e](P(-(% H)(D 6)-1)H)](A b[M]e)))))

Đầu vào mẫu và trường hợp thử nghiệm:

(def mymsg (clojure.string/upper-case "We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot#3#"))
(def mykey "SENATORI")
(def mypharase (clojure.string/upper-case (apply str (remove #{\space} "The first principle is that you must not fool yourself — and you are the easiest person to fool."))))
(def mydate [3 1 7 2 0 1 6])
(def mynum 9)
(def M [4 7 9 2 1])

;("61231" "12824" "71192" "58609" "92185" "48612" "14927" "22944" "34046" "13348" "04159" "38645" "70546" "20254" "22026" "64584" "21904" "47921" "90253" "42694" "42221" "56644" "14541")
(enc mymsg mykey mypharase mydate mynum M)

Ung dung:

(defn enc[mymsg mykey mypharase mydate mynum M]
  (let[t       10
       r       (range t)
       m       (fn[i](mod i t))
       lagfib  (fn[[n & N]](map last(iterate(fn[[[b & N]a]][(concat N[(m(+ a b))])b])[N n])))
       toseq   (fn[S](for[i(range(count S))a[(nth S i)]](apply +(count(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))
       [S1 S2] (map toseq(split-at t(take 20 mypharase)))
       M2      (take t(lagfib(map - M mydate)))
       G       (map m(map + S1 M2))
       Gmap    (zipmap r S2)
       T       (map Gmap G)
       U       (take 50(drop t(lagfib T)))
       L2      (last U)
       L1      (last(remove #{L2}U))
       p       (+ mynum L1)
       q       (+ mynum L2)
       seqT    (toseq T)
       V       (mapcat(zipmap seqT(apply map vector(partition t U)))r)
       [K1 K2] (map toseq(split-at p(take(+ p q)V)))
       C       (toseq(reverse(take t(reverse U))))
       B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(*(quot i 10)20)(nth C(m i)))])(range)(concat(str mykey",,")(remove(set mykey)(map char(concat(range 65 91)".#"))))))
      ;B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(nth C(quot i 3))(*(mod i 3)20))])(range)(flatten(apply map vector(partition 10(apply concat mykey",,"(apply map vector (partition 2(remove(set mykey)(map char(concat(range 65 91)".#")))))))))))
       N1      (count K1)
       mymsg   (flatten(partition 5(concat(mapcat str(map B(let[[b e](split-at 49 mymsg)](apply str(concat e".. "b)))))(repeat 4(B\,)))))
       T1      (vec(filter some?(mapcat(zipmap K1(apply map vector(partition N1(concat mymsg(repeat(dec N1)nil)))))(range N1))))
       N2      (count K2)
       NR      (+(quot(count T1)N2)1)
       cols    (flatten(for[k r](for[i(range(.indexOf K2 k)(+(count K2)1))](range i))))
       rows    (rest(reductions + -1(map(fn[i](get{0 1}i 0))cols)))
       coords  (for[[r c](map vector rows cols):when(< r NR)][r c])
       coords  (concat coords(for[i(range NR)j(range N2)c[[i j]]:when(not((set coords)c))]c))
       T2      (partition 5(filter some?(mapcat(zipmap K2(apply map vector(partition N2(concat(vals(into(sorted-map)(map vector coords T1)))(repeat(dec N2)nil)))))(range N2))))]
    (map(fn[p](apply str p))(let[[b e](split-at(-(count T2)(mydate 6)-1)T2)](concat b[M]e)))))

Nó có một triển khai thay thế trên bàn cờ Bgiống như trên định nghĩa tác vụ. Nhưng bài nộp sử dụng một bảng khác trong đó các bảng chữ cái không được sử dụng trước tiên điền vào hàng thứ 2 và sau đó là thứ 3 thay vì điền từng cột.


Được coi là viết một giải pháp Clojure, nhưng đầu tôi nổ tung khi tôi đang đọc câu hỏi. Mất bao lâu để viết?
Carcigenicate

Có lẽ 3 giờ trong khi xem Youtube ở bên. Điều này bắt đầu khá dễ dàng nhưng tôi đã bỏ cuộc khi phải thực hiện "chuyển vị bị gián đoạn" thứ hai. Bây giờ thìcoords được tạo hai lần, đầu tiên tạo hình tam giác và sau đó điền vào bất kỳ tọa độ nào bị thiếu. Ngoài ra, "đệm theo chiều dài nhân của N" có thể có giải pháp thanh lịch hơn so với ghép các phần tử N - 1 và phân vùng theo độ dài của N.
NikoNyrh

Ôi chết tiệt, tôi đã quên thay đổi điểm phân tách được mã hóa cứng tại (split-at 49 mymsg), 49 sẽ là một cái gì đó giống như (rand-int(count mymsg))câu trả lời đúng sẽ là hơn 1200 byte. zzz
NikoNyrh

Chỉ trích. Có lẽ vẫn còn ít hơn câu trả lời c mặc dù.
Carcigenicate
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.