7 , 2 byte
7 sử dụng bộ ký tự 3 bit, nhưng lấy đầu vào được đóng gói thành byte (và theo meta, các ngôn ngữ có bộ ký tự byte phụ được tính bằng byte cho tệp trên đĩa ). Đây là một xxd
bãi chứa chương trình:
00000000: 4cf4 L.
Khi đưa tệp này cho 7 trình thông dịch, nó sẽ xuất chương trình sau:
00000000: 4fa6 7f O..
mà sau đó sẽ lần lượt xuất chương trình gốc một lần nữa.
Vậy chuyện gì đang xảy ra ở đây? Không có việc đọc nguồn liên quan (thực ra, tôi không nghĩ có thể đọc nguồn trong 7), mặc dù có thể cho rằng chương trình này gian lận theo một cách khác; cho tôi biết bạn nghĩ gì. Đây là cách chương trình hoạt động. (Lưu ý rằng mỗi lệnh 7 có hai biến thể, một số biến thể không có tên và không thể xuất hiện trong chương trình gốc. Có tổng cộng mười hai lệnh, trong sáu cặp. Tôi đang sử dụng đậm cho các lệnh đang hoạt động, không được gọi là bị động các lệnh và trong trường hợp lệnh hoạt động không có tên, tôi đặt cho nó cùng tên với lệnh thụ động tương ứng và dựa vào chữ in đậm để phân biệt. Trong trường hợp cả hai được đặt tên, ví dụ: 7
đó là biến thể hoạt động của 1
, mỗi lệnh có tên riêng và đậm chỉ là tô sáng cú pháp.)
231 7 23 Chương trình gốc, giải nén thành bát phân
Đẩy đẩy 237 lên ngăn xếp
23 Đẩy 23 lên ngăn xếp
(ngầm) nối một bản sao của đỉnh ngăn xếp vào chương trình
2 Sao chép đỉnh của ngăn xếp (hiện tại là 23 )
3 Đầu ra của ngăn xếp, phần tử ngăn xếp thứ hai pop
Tại thời điểm này, 7 trình thông dịch thấy rằng đỉnh ngăn xếp chứa các lệnh ( 2
và 3
) không thể biểu thị được, vì vậy nó thoát khỏi đỉnh ngăn xếp, tạo ra 723
(đó là). Đầu ra lệnh đầu tiên chọn định dạng đầu ra; trong trường hợp này, nó là định dạng 7, "định dạng đầu ra giống như chương trình". Vì vậy, các lệnh được đầu ra đóng gói thành byte. Sau đó, chương trình tiếp tục:
231 7 23 23
(ngầm) nối một bản sao của đỉnh ngăn xếp vào chương trình
2 Sao chép đỉnh của ngăn xếp (hiện tại là 237 )
3 Đầu ra của ngăn xếp, bật phần tử ngăn xếp thứ hai
7 Đẩy một phần tử trống lên ngăn xếp
Tại thời điểm này, không có gì ngoài các phần tử ngăn xếp trống trên ngăn xếp, vì vậy chương trình sẽ thoát. Chúng tôi đầu ra 23
sớm hơn. Nếu chúng ta thoát 237
(và chúng ta phải, bởi vì nó chứa các lệnh không thể diễn tả được), chúng ta sẽ nhận được 7231
. Điều đó nhận đầu ra trực tiếp, làm cho đầu ra cuối cùng của chương trình 237231
(được định dạng giống như chương trình, nghĩa là được đóng gói thành byte). Đó là 4fa67f
. (Có thể lưu ý rằng điều 1
này hoàn toàn vô nghĩa về mặt ảnh hưởng đến đầu ra; lý do duy nhất là nó làm cho hai chương trình khác nhau.)
Chạy 237231
tiến hành gần như chính xác cùng một cách; sự khác biệt là phần vô dụng 1
chạy ngay sau lần in đầu tiên (và phần tử trống sẽ bị xóa hoàn toàn lần thứ hai khi kết thúc chương trình hiện tại đạt được). Một lần nữa, 231
kết thúc xuất ra chính nó, 23
kết thúc xuất ra trước một 7
, và chúng tôi nhận được 231723
, chương trình ban đầu.
Người quan sát có thể lưu ý rằng hai chương trình, mặc dù có cùng độ dài trong bát phân "bản địa" của ngôn ngữ, có độ dài khác nhau trên đĩa. Đó là bởi vì một chương trình 7 có thể được đệm với số lượng 1 bit tùy ý và định dạng được đóng gói sẽ loại bỏ phần đệm. Đây là cách mã hóa xảy ra:
2 3 1 7 2 3
010011001111010011(1...)
4 c f 4 padding
Nói cách khác, hai byte, 4C
F4
là đủ để đại diện cho chương trình, vì vậy đó là tất cả những gì tôi sử dụng.