Chương trình này có đầy đủ các ký tự không thể in được, vì vậy đây là một hexdump:
00000000: 2573 dc01 7e13 dcb6 1f %s..~....
Lưu ý: điều này sử dụng một thói quen đầu vào số không có khả năng nhập số âm, vì vậy việc gửi này chỉ bị giới hạn ở các số nguyên không âm.
Một vấn đề với các thách thức của cảnh sát và tên cướp là bạn không viết các giải thích về mã (để làm cho nó khó bị bẻ khóa hơn). Mặt khác, điều này có nghĩa là tôi không phải gặp rắc rối ở đây.
Tôi đã chọn 7 làm ngôn ngữ bởi vì, đặc biệt là trong ký hiệu nén của nó, nó khá khó đọc và tôi không hiểu tại sao chỉ có tôi là người phải gặp rắc rối khi di chuyển xung quanh các chương trình 8 bit được viết trong mã hóa 3 bit. Chúc may mắn!
Giải trình
Bây giờ, chương trình đã bị bẻ khóa (không may bằng vũ lực, thật không may, đó luôn là mối nguy hiểm trong các giải pháp ngắn này), tôi cũng có thể giải thích những gì tôi đang làm. Điều này thực sự khá khả thi bằng cách đọc chương trình; Tôi có thể đã làm cho nó khó khăn hơn nhiều, nhưng cảm giác đó là một ý tưởng tồi khi các vết nứt vũ phu tồn tại.
Chúng ta sẽ bắt đầu bằng cách trình bày chương trình theo cách mã hóa tự nhiên hơn. Như thường lệ, số in đậm chỉ ra lệnh chạy ngay lập tức (không phải tất cả trong số đó là biểu diễn trong một chương trình; 6
và 7
chỉ là 2
để 5
không), số unbolded đại diện tương đương trốn thoát của họ ( 0
để 5
, tất cả trong số đó là biểu diễn trong chương trình gốc; lưu ý đó 0
là một người trốn thoát 6
và 1
là một người trốn thoát 7
):
112 7 1 7 34002 77 023 67 13303
Tập hợp các lệnh có sẵn trong nguồn 7 chương trình có nghĩa là về cơ bản nó chỉ là một chữ đại diện cho ngăn xếp ban đầu (bạn không thể làm gì khác chỉ với các lệnh đã thoát 6
và 7
). Vì vậy, điều đầu tiên một chương trình sẽ làm là đẩy một loạt các thứ lên ngăn xếp. Đây là cách ngăn xếp sau khi chương trình chạy ( |
tách các phần tử ngăn xếp, như thường lệ trong 7):
772 | 7 | 34662 | 023 | 73363
Phần tử ngăn xếp cuối cùng sau đó được sao chép để trở thành mã để chạy (trong khi còn lại trên ngăn xếp). Khi nó xảy ra, đây là phần duy nhất của chương trình đó là mã; mọi thứ khác chỉ là dữ liệu. Đây là những gì nó dịch là:
73363
7 Đẩy phần tử trống lên ngăn xếp
3 Xuất phần tử ngăn xếp trên cùng, loại bỏ phần tử bên dưới
73 Hiệu ứng kết hợp của các phần tử này: loại bỏ phần tử ngăn xếp trên cùng
3 Xuất phần tử ngăn xếp trên cùng, loại bỏ phần tử bên dưới
6 Thoát phần tử ngăn xếp trên cùng, sau đó nối nó vào phần tử bên dưới
3 Xuất phần tử ngăn xếp trên cùng, loại bỏ phần tử bên dưới
Nói cách khác, đây chủ yếu chỉ là một loạt các hướng dẫn I / O. Hãy phân tích chi tiết này:
73
loại bỏ cái 73363
vẫn còn trên đỉnh của ngăn xếp.
3
xuất ra 023
và loại bỏ 34662
. Do đó có thể thấy rằng đó 34662
là một nhận xét, được sử dụng để lưu trữ các byte cần thiết trong phiên bản khác của chương trình. Đối với những gì 023
khi đầu ra, nó chọn định dạng I / O 0 (số nguyên), sau đó 23
là một lệnh yêu cầu thực hiện để nhập một số nguyên (trong 7, bạn thực hiện nhập thông qua xuất ra các mã cụ thể yêu cầu đầu vào). Đầu vào được thực hiện bằng cách tạo các bản sao của phần tử ngăn xếp bên dưới, ví dụ: nếu số nguyên đầu vào là 10, phần tử ngăn xếp tiếp theo (hiện tại 7
) sẽ trở thành 7777777777
. Do đó, chúng tôi chấp nhận đầu vào từ người dùng ở dạng thập phân, nhưng nó được lưu trữ dưới dạng đơn nguyên.
6
thoát khỏi phần tử ngăn xếp trên cùng (thay đổi từng phiên bản 7
thành 1
; đây là cách các chuỗi bao gồm toàn bộ 7
s được thoát), sau đó nối nó vào phần tử ngăn xếp trước ( 772
). Vì vậy, dữ liệu của chúng tôi bây giờ là một cái gì đó như 7721111111111
.
- Cuối cùng,
3
xuất ra phần tử ngăn xếp trong câu hỏi (và bật một phần tử ngăn xếp trống là một phần của ngăn xếp ban đầu mặc định). Giá trị của nó được tính bằng cách lấy số 1
s và 7
s, và trừ đi số 0
s và 6
s. (Ở 2
giữa được bỏ qua trong hầu hết các trường hợp; nếu ở cuối chuỗi, nó sẽ trở thành một dòng mới thay vì bị bỏ qua, nhưng các quy tắc PPCG không quan tâm đến điều đó.) Vì vậy, đầu ra là bản gốc đầu vào cộng 2.
Tại thời điểm này, không có gì hữu ích trên ngăn xếp và không có gì trong chương trình, vì vậy chương trình thoát.
Làm thế nào để chúng ta đảo ngược điều này? Đây là một vấn đề đơn giản để thay đổi 11
thành 00
, để chúng tôi chuẩn bị các ký tự cho đầu vào làm cho nó thấp hơn 2, thay vì 2 cao hơn. Có 00
tám chữ số bát phân được ẩn một cách thuận tiện hơn nữa trong chương trình (để các chữ số bát phân và byte thẳng hàng với nhau), vì vậy chúng ta có thể chỉ cần trao đổi nó với 11
lúc bắt đầu.