Cops và Robbers: Redacted Primality (Chủ đề của kẻ cướp)


9

Đây là chủ đề của bọn cướp. Chủ đề của cảnh sát ở đây .

Thách thức của bạn là lấy một bản đệ trình không bị bẻ khóa từ chuỗi của cảnh sát và cố gắng tìm chương trình chưa được xác thực ban đầu. Vui lòng nhận xét về trình của cảnh sát khi bạn bẻ khóa mã của họ.

Câu trả lời:


6

cân não , Jo King

>>>>>+>,[>++++++[-<-------->]<+>,]<[-[█<█<]++++++++++<]>[-]>>██[>█>>█>]+[<]<<[<]>█<<+>>[>]█>[>]█+[<]<<[<]>-█>]>>[->]<[-[[<]<]++++++++++<]>[-]>[<█]>]>[>]<[[█]<]<<<<<[<]<<██>>[>]<█[->+<]<█>>[>]<[-[[<]<]++++++++++<]>███>[<<]>[[[>]>████[<]<[-[[<]<]++++++++++<]>[-]>[█<]>]>[>]<[[-]>+[>]<-<[<]<]+<<<<<[<]>[[>]+[[>]>]>[>]>[-<+>]<[<]<[>+[<]>>-<<<<<[[<]<]>>███████>[[█]>]<]<[[<]<]<[█]>]>>>[[>]<->>]]>[[>]>]<<[[[█]<]<]<<<[█]<<█>>>[>]█[-[[<]<]++++++++++<]>>[[>]+[------->++<]>.+.+++++.[---->+<]>+++.>>]>[>]+[------->++<]>++.++.---------.++++.--------.
>>>>>+>,[>++++++[-<-------->]<+>,]<[-[[<]<]++++++++++<]>[-]>>[[[>]>>[>]+[<]<<[<]>[<<+>>[>]>>[>]<+[<]<<[<]>-]>]>>[->]<[-[[<]<]++++++++++<]>[-]>[<<]>]>[>]<[[-]<]<<<<<[<]<<[>>>[>]<[[->+<]<]>>[>]<[-[[<]<]++++++++++<]>[-]>[<<]>[[[>]>[>]+[<]<[-[[<]<]++++++++++<]>[-]>[<<]>]>[>]<[[-]>+[>]<-<[<]<]+<<<<<[<]>[[>]+[[>]>]>[>]>[-<+>]<[<]<[>+[<]>>-<<<<<[[<]<]>>[[-]+>]>[[>]>]<]<[[<]<]<[<]>]>>>[[>]<->>]]>[[>]>]<<[[[-]<]<]<<<[<]<<]>>>[>]<[-[[<]<]++++++++++<]>>[[>]+[------->++<]>.+.+++++.[---->+<]>+++.>>]>[>]+[------->++<]>++.++.---------.++++.--------.

Hãy thử trực tuyến!

Điều này thực hiện sàng của Eratosthenes.

Đầu >>>>>+>,[>++++++[-<-------->]<+>,]vào ban đầu mỗi chữ số dưới dạng mã ký tự và trừ 47 để đặt nó trong phạm vi 1-10. Điều này cho phép giá trị ô là 0 để biểu thị khoảng cách giữa các số. Phần +>gần đầu của phần này buộc số phải có ít nhất hai chữ số, điều này sẽ sớm quan trọng.

Tiếp theo, và một trong những điều đầu tiên tôi tìm ra, là phần <[-[[<]<]++++++++++<]>[-]>. Điều này xuất hiện nhiều lần trong mã, mỗi mã có các kiểu phân chia khác nhau, nhưng không khó để đoán rằng tất cả các trường hợp đó có thể là cùng một mã. Mã này yêu cầu ba số không ở bên trái của số thập phân trên băng và tác dụng của nó là làm giảm số. Lặp lại cuối cùng của vòng lặp sẽ đặt giá trị 10 hai ô còn lại của số, nhưng [-]làm sạch nó.

Nếu số thập phân là 0, không có số 10 không liên tục được tạo và ô không [-]có giá trị là chữ số có nghĩa nhất. Đầu băng sau đó là chữ số có ý nghĩa thứ hai (đó là lý do tại sao ít nhất hai chữ số là cần thiết). Hầu hết các trường hợp của đoạn mã này ngay lập tức được theo sau [<<]>, đặt đầu trên một ô khác không trong điều kiện bình thường và một ô bằng 0 nếu số thập phân ban đầu bằng không. Có vẻ như trong chương trình này, biểu diễn thập phân của n-1được sử dụng để biểu thị n, do đó, phần giảm dần 0được bắt thay vì giảm xuống -1.

Phần tiếp theo đặt các số từ n-1 (n) xuống 0 (1) trên băng:

>[                      until the number reaches zero:
  [                     for each digit:
    [>]>>[>]+[<]<<[<]>  create a placeholder for the next copy
    [                   while the original value of the digit is nonzero:
      <<+               add 1 to copy two cells left (to keep one copy)
      >>[>]>>[>]<+      go to new copy and increment that cell
      [<]<<[<]>-        go back to original digit and decrement
    ]                   (this is effectively the same as [<+>>+<-] but with the cells at variable locations)
  >]                    next digit
  >>[->]                cancel the placeholder 1s that were used for the new copy
  <[-[[<]<]++++++++++<]>[-]>[<<]> decrement
]
>[>]<[[-]<]      clean up the trash 10s on the tape while ending at a known location relative to the last number

Bây giờ, những con số này là tất cả trên băng với hai ô số 0 ngăn cách chúng. <<<<<[<]<<đặt chúng ta vào ô cuối cùng của số áp chót trên băng, đó là nơi chúng ta sẽ ở trong mỗi lần lặp của vòng lặp. Vòng lặp chấm dứt khi tất cả các số trừ bản gốc đã được xử lý.

Khi bắt đầu vòng lặp, chúng tôi di chuyển số hiện tại (số cuối cùng vẫn còn trên băng) một ô bên phải để có chỗ để giảm, sau đó tiếp tục và giảm dần:

[>>>[>]<[[->+<]<]>>[>]<[-[[<]<]++++++++++<]>[-]>[<<]>

Nếu phần giảm này không được thực hiện, chúng tôi tiến hành chuyển đổi số thành đơn vị:

[[[>]>[>]+[<]<[-[[<]<]++++++++++<]>[-]>[<<]>]

Lưu ý rằng snipped này có một không rõ ràng [. Kết quả là phần còn lại của vòng lặp này bị bỏ qua nếu số là 0 (đại diện cho 1). Sau khi chuyển đổi thành unary, chúng tôi xóa số 10 còn lại, kéo đại diện đơn nguyên với chúng tôi sang bên trái:

>[>]<[[-]>+[>]<-<[<]<]+

Tôi đã không nhận thấy cho đến khi viết bài này, nhưng +ở phần cuối của đoạn trích này được tách ra khỏi biểu diễn đơn nhất bằng một số 0. Nó cũng là một phần của biểu diễn đơn nguyên: chuỗi 1011...11sẽ đại diện cho 0 mod k. Sau đây <<<<<[<]>đặt chúng ta ở đầu số k+1, bắt đầu một vòng lặp mới.

Vòng lặp bên trong ở đây "đánh dấu" mọi số trên băng bằng 1 trên ô ngay lập tức và sử dụng biểu diễn đơn nhất làm đồng hồ để xác định số nào là bội số của k.

[
  [>]+             mark the current decimal number
  [[>]>]           move to end of decimal part of tape
  >[>]             move to 0 in middle of unary "clock"
  >[-<+>]          move the following 1 to the left if possible
  <[<]<            if a 1 was moved this will bring us back to a zero before the start of this "clock";
                   otherwise the looped move command doesn't move us at all and we are at the final 1
  [                if there was no gap (happens every kth iteration):
    >+[<]>>-       reset to original position
    <<<<<[[<]<]>>  go to number that was just marked
    [[-]+>]        replace digits with 0s (cell value 1)
    >[[>]>]<       go back to where we would be without this conditional
  ]
  <[[<]<]<[<]>     return to first unmarked number
]

Phần [[-]+>]đó là phần cuối cùng tôi tìm ra. Trước đó, tôi cho rằng chương trình chỉ đang thực hiện các thử nghiệm, nhưng tôi không thể thấy kết quả được sử dụng ở đâu.

Vòng lặp này kết thúc hai ô bên trái của số xa bên trái và >>>[[>]<->>]]loại bỏ các điểm đánh dấu được đặt trên băng và đưa chúng ta đến cuối băng một lần nữa. Sau đó, >[[>]>]<<[[[-]<]<]loại bỏ đồng hồ đơn nguyên hoặc, nếu toàn bộ phân đoạn này bị bỏ qua, 10 giây còn lại. Vòng lặp được đặt thành điều kiện bắt đầu với <<<[<]<<].

Sau đó, chỉ cần đọc liệu số đầu vào đã được thay thế bằng 1 tại bất kỳ điểm nào:

>>>[>]<[-[[<]<]++++++++++<]>>                      do the check
[[>]+[------->++<]>.+.+++++.[---->+<]>+++.>>]      conditionally print "not "
>[>]+[------->++<]>++.++.---------.++++.--------.  unconditionally print "prime"

May mắn thay, sản lượng thực tế đã không được điều chỉnh lại.


"Đêm dài mà không bao giờ tìm thấy ngày." Có còn đêm nay không? : P
Stewie Griffin

@StewieGriffin Tôi đã không thể làm điều đó tối hôm đó, và sau đó nó chỉ trượt tâm trí của tôi. Cảm ơn đã nhắc nhở.
Nitrodon

Tôi không nghĩ rằng tôi có thể đã giải thích mã của riêng tôi cũng như bạn đã làm ở đây. Công việc rất tốt.
Jo King

5

Ngôn ngữ Wolfram (Mathicala)

Nứt câu trả lời này .

f[x_]:=(p=ToString@Boole@PrimeQ@x;StringMatchQ[p&@@Infinity,RegularExpression@"(\
\n{}\b+, )?1"])

Hãy thử trực tuyến!


Không cần cuộn để đọc mã :)
user202729

Đẹp! Hoàn toàn khác với giải pháp dự định, vì vậy tôi sẽ không tiết lộ điều đó.
Pavel

@Pavel Còn cái này thì sao? Hay vẫn "cơ bản giống nhau"?
dùng202729

Dưới đây là một gợi ý: đó blob lớn chứa không phải Boolekhông PrimeQ.
Pavel

5

Brain-Flak, MegaTom

(({████){██[████)█>(({}))<>}<>{}███{}((██({}))█████{}]██)({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})██[██()██(()█[()]██{}██}{}<>{})
(({})<>){([[]]{})<>(({}))<>}<>{}{}{{}(([]({}))[({}[{}])])({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})}([][()])((){[()](<{}>)}{}<>{})

Hãy thử trực tuyến!

Chương trình này thực hiện các phân chia thử nghiệm từ n-2 xuống 1, sau đó xuất 1 khi và chỉ khi điều này kết thúc với yếu tố 1.


4

8086 DOS COM của Joshua

xxd đại diện, vì mã hóa và byte rỗng và các thứ đáng sợ khác:

00000000: 31c0 b90a 0031 dbbe 8100 ac3c 0d74 3c3c  1....1.....<.t<<
00000010: 2075 f7ac 3c0d 7410 2c30 7c2f 3c09 7f2b   u..<.t.,0|/<..+
00000020: 93f7 e193 01c3 ebeb 83fb 027c 19c6 0653  ...........|...S
00000030: 0159 b902 0039 d974 1289 d831 d2f7 f109  .Y...9.t...1....
00000040: d274 0341 ebef c606 5301 4eb4 09ba 5301  .t.A....S.N...S.
00000050: cd21 c341 0d0a 24                        .!.A..$

Đầu tiên tháo rời cảnh sát bằng tay, sau đó lắp ráp bằng cách sử dụng yasm. Một số byte đã bị hỏng bởi bộ chuyển đổi Joshua đã sử dụng, nhưng tôi chỉ coi chúng như các byte được điều chỉnh lại. Tôi chắc chắn 99,72% về nội dung thực tế của họ. Tuy nhiên, sẽ không mất nhiều thời gian để sửa nó nếu tôi sai. Thưởng thức:

; A COM file is just a 16-bit flat binary
; loaded at 0x100 in some segment by DOS

org 0x100
bits 16

; Unsurprisingly, we start by converting
; the commandline string to a number. During
; the conversion, SI is a pointer to the
; string, CX is the base, and BX holds the
; partial result
parse_input:
; We'll read the input character by character
; into AL, but we need the resulting digit as
; a 16-bit number. Therefore, initialise AX to
; zero.
    xor ax, ax
    mov cx, 10
    xor bx, bx
; When a DOS program is loaded, it's preceded
; in memory by the Program Segment Prefix,
; which holds the commandline arguments at
; offset 0x81, terminated by a carriage return
    mov si, 0x81

.skip_prog_name:
; Load a character and move the pointer
    lodsb
; If we find the terminator here, the program
; was not given any arguments.
    cmp al, 13
    je finish

    cmp al, ' '
    jne .skip_prog_name

.input_loop:
    lodsb
    cmp al, 13
    je got_input

; If the ASCII value of the character is less
; than the one of '0', error out. Adjust the
; value in AL so that it holds the digit
; itself. This exploits the fact that the
; comparison instruction is just a subtraction
; that throws away the actual result.
    sub al, '0'
    jl finish

; If we have a value larger than 9, this
; character wasn't a digit.
    cmp al, 9
    jg finish

; Multiply the intermediate result by 10 and
; add the new digit to it.

    xchg ax, bx
    mul cx
    xchg ax, bx
    add bx, ax
    jmp .input_loop

got_input:
; The loop below would go haywire when given a
; zero or a one, so make them a special case.
    cmp bx, 2
    jl composite

; Patch the output string to say that it's
; prime
    mov byte[outstr], 'Y'

; BX = number being checked
; CX = loop counter, potential divisor of BX
    mov cx, 2

.loop:
; If CX = BX, we looked everywhere and couldn't
; find a divisor, therefore the number is prime
    cmp cx, bx
    je finish

; DIV takes DX:AX as a 32-bit number for the
; dividend. We don't want nor need the extra
; precision, so we set DX to 0.
    mov ax, bx
    xor dx, dx
    div cx

; DX now contains the remainder. To check if
; it's 0, we perform some noop operation, that
; happens to set the flags appropriately. AND
; and OR are commonly used for this purpose.
; Because of what's presumably a bug in the
; encoder used by Joshua, I do not yet know
; which for certain. However, I can make an
; educated guess. All other instances of the
; bug happened with a codepoint below 32.
; Moreover, no other bytes from that range
; occur in the code. Because an AND would be
; encoded as an exclamation mark, while OR -
; - as a tab, I am highly confident that Joshua
; used an OR.
    or dx, dx
    jz composite

; Increment the counter and loop again!
    inc cx
    jmp .loop

composite:
    mov byte[outstr], 'N'

finish:
    mov ah, 9
    mov dx, outstr
    int 0x21
    ret

outstr:
    db 'A', 13, 10, '$'

Sự khác biệt duy nhất giữa tôi là bx < 2đi đến kết thúc chứ không phải tổng hợp. FYI tham nhũng là do ban đầu sử dụng X làm nhân vật mặt nạ và không sửa chữa mọi thứ đúng cách khi chuyển sang.
Joshua

@Joshua Lúc đầu tôi cũng dùng xong, nhưng sau đó tôi nhớ rằng xử lý 1 chính xác là bắt buộc. Về tham nhũng - đó là một trong những kịch bản tôi tưởng tượng
NieDzejkob

3

Thạch

Nứt câu trả lời này .

25██26█966836897364918299█0█1█65849159233270█02█837903312854349029387313█ị██v
250126,9668368973649182994001,658491592332700020837903312854349029387313ṖịØJv

Hãy thử trực tuyến!


Giải trình:

Nhìn vào v, tôi nghĩ đến việc xây dựng một danh sách các số, ndex nó vào một số danh sách và đánh giá nó.

Cách kiểm tra tính nguyên thủy "tầm thường" trong Jelly là ÆP, vì vậy (nếu nó có thể phá vỡ sự đệ trình):

  • Danh sách được lập chỉ mục phải chứa ÆP.
  • Danh sách các chỉ số phải được modulo đồng dạng 256với [14, 81].

Vì vậy, ... danh sách khi bắt đầu chương trình phù hợp với [14, 81, 49]mod 256 ( TIO ) và bật phần tử cuối cùng.


3

sh + lõi

Nứt câu trả lời này .

eecs c "██████WyAkKHNoIC1jICJg█WNobyBabUZqZEc5eWZIUnlJQ2█2SnlBblhHNG5m██JoYVd3Z0t6SjhkMk1nTFhjSyB8YmFzZTY0IC1kYCIpIC1lcSAxIF0K█b█se6███d`"
exec sh -c "`echo WyAkKHNoIC1jICJgZWNobyBabUZqZEc5eWZIUnlJQ2M2SnlBblhHNG5mSFJoYVd3Z0t6SjhkMk1nTFhjSyB8YmFzZTY0IC1kYCIpIC1lcSAxIF0K|base64 -d`"

Không thử trực tuyến! lần này vì một số vấn đề . Tuy nhiên bạn có thể sử dụng jdoodle .

Trả về bằng mã thoát. 0(thành công) cho số nguyên tố, 1(lỗi) cho tổng hợp.

Lệnh thực tế được thực hiện là

factor|tr ':' '\n'|tail +2|wc -w

Cách bẻ khóa

  1. Nhìn vào mã, nhận ra Base64.
  2. Học cách sử dụng base64 lệnh.
  3. Biết rằng đó +là một ký tự base64 hợp lệ.
  4. Cố gắng giải mã .
  5. Áp dụng trình bao bọc sh -c "`echo ...|base64 -d`"trở lại chương trình ban đầu .
  6. Tạo base64 lồng nhau từ các lệnh .

Phương pháp đúng. "Một số vấn đề" hóa ra không phải tất cả các máy đều biết tail +n. Khi tôi thử crack của bạn trên máy tại nơi làm việc, nó đã phàn nàn về nó. Bạn đã vạch mặt mã chính xác nên ... :(
Joshua

3

Octave , 86 byte, Stewie Griffin .

@(x)eval([(str2num(cell2mat([cellstr(reshape('0█1███1█0█0█00',████))])')'█')','(x)'])
@(x)eval([(str2num(cell2mat([cellstr(reshape('04141113040800',2,[]))])')+'e')','(x)'])

Hãy thử trực tuyến!

Đây là một niềm vui! Tôi đã vật lộn với điều này trong một vài ngày.

Manh mối đầu tiên được nhận ra eval([...,'(x)'])là một công trình tạo ra một lời gọi đến isprimehàm, khi nối intscharsẽ ngầm chuyển đổi mảng thành char, do đó, ...cần phải là một isprimehoặc một mảng có các giá trị ASCII của isprime, [105, 115, 112, 114, 105, 109, 101].

Phần còn lại của nó chỉ là lén lút thông qua tài liệu để tìm ra rằng reshapecó thể mất một chiều không xác định [], mặc dù tôi cho rằng tôi có thể đã làmreshape(...,2, 7) ở cùng một số byte.

Sử dụng +'e'(101) thay vì +'d'(100) là một liên lạc tốt đẹp đã ném tôi thêm vài phút nữa cho đến khi tôi nhận thấy các chữ số cuối cùng ( 00không bị ảnh hưởng) thì đúng hơn 01, và điều đó thật dễ dàng.


2

JavaScript

x=>{if(x<4)return(!0);for(y=x>>>Math.log10(p=████;--y-1;(p=x/y%1)████if(██&&(███))break████return(███)}
x=>{if(x<4)return(!0);for(y=x>>>Math.log10(p=2-1);--y-1;(p=x/y%1)){;;if(!p&&(1<2))break;;;}return(!!p)}

Hãy thử trực tuyến!

Tôi bằng cách nào đó nghi ngờ đây là chính xác những gì bạn có trong tâm trí, nhưng nó hoạt động.


2

> <> , Esolanging trái cây

:1@v>~~:?1n;█$-1<█?=2:}*{█@:$@:

đến

:1@v>~~:?1n;
$-1</?=2:}*{%@:$@:

Hãy thử trực tuyến!

Khéo léo sử dụng sắp xếp lại một dòng mới làm tôi bối rối một chút. Dường như không hoạt động trong 1 hoặc 2.


Đẹp. Bất kỳ ^, v, /, hoặc \ cho vào chỗ trống thứ hai có thể đã làm việc ở đó. Bây giờ tôi muốn tôi đã bảo hiểm *thay vì /.
Esolanging Fruit 6/2/18

2

Java (OpenJDK 8) , Bạch tuộc ma thuật Urn

class X{public static void main(String[]args){System.out.println(new String(████████[Integer.parseInt(args[0])]).matches("█████████████")?███);}}
class X{public static void main(String[]args){System.out.println(new String(new char[Integer.parseInt(args[0])]).matches(".?|(..+?)\\1+")?0:1);}}

Hãy thử trực tuyến!

Mã được lấy từ RosettaCode và được giải thích trên SO .


Không có ý tưởng rằng nó là phổ biến hah! Có cái này trong túi sau của tôi trong một thời gian dài. Tôi thực sự đã đánh cắp nó từ một tập tin tiện ích mà tôi đã có từ ... Jeez ... 2014?
Bạch tuộc ma thuật Urn

2

Python 3 , 44 byte, osuka_

p=lambda x,i=2:i>=x or(x%i and p(x,i+1))or 0

Hãy thử trực tuyến!

Không hoạt động khi x <2. Có or 0thể được thay thế bằng >0{2 spaces}hoặc thậm chí 4 không gian

Đối với vấn đề x <2, do i>=xphải được đặt ở phía trước (nếu không sẽ có một vòng lặp vô hạn) và i>=xtrả về đúng ngay lập tức khi x <2, vì vậy tôi nghĩ rằng không có cách khắc phục nào.


Vì vậy, hóa ra, mã của tôi cũng không hoạt động với x <2. Giáo sư. (Có lẽ tôi chỉ thử nó với phạm vi (2, ...), vì tôi ngu ngốc)
osuka_

2

M, dyl Nam

ÆPø“;;“»VOḣ2S⁵++3Ọ;”Pv

Đây có lẽ không phải là giải pháp dự định.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

ÆP là bài kiểm tra nguyên thủy tích hợp.

øchúng sinh một chuỗi mới, niladic. Vì giá trị trả về trước đó (kết quả của ÆP) nằm ngoài phạm vi, điều này sẽ in nó hoàn toàn.

“;;“»đánh giá danh sách các chuỗi ["< Aalst" ""]Vcố gắng đánh giá chúng. scố gắng phân tách đối số của nó thành các đoạn có độ dài 0 , khiến trình thông dịch M bị sập, triệt tiêu đầu ra tiếp theo.


Không có giải pháp dự định nhưng tốt đẹp. Sẽ cập nhật bài viết để crack sớm. Nếu tôi nói từ vườn bách thú, điều đó sẽ dẫn bạn đến một giải pháp khả thi khác?
dyl Nam

Hừm, nghe có vẻ vô cùng phức tạp.
Dennis


1

Python 3 , người dùng71546

import random
def f(z):
 if z<4:return z>>1
 d,s,n,e,c=~-z,0,z,0,50
 while not d&1:d//=2;s+=1
 while n>0:n//=2;e+=1
 random.seed()
 while c>0:
  a=0
  while a<2or a>z-1:
   a,b=0,e
   while b>0:a=a*2+random.randint(0,1);b-=1
  x,r=pow(a,d,z),~-s
  if ~-x and x!=~-z:
   while r>0:
    x,r=pow(x,2,z),~-r
    if not ~-x:return 0
    elif x==~-z:break
   else:return 0
  c-=1
 else:return 1

Hãy thử trực tuyến!

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.