Giải mã script bash bị làm rối trên áo thun Uniqlo
(tris.sherliker.net)- Áo thun thiết kế Akamai bán tại cửa hàng Uniqlo có in mã bash bị làm rối, chạy kết quả của
base64 --decodebằngeval, nhưng thực ra đây là một easter egg cho chiến dịchPeace for All - Khi giải mã Here string được mã hóa Base64, ta nhận được một script lặp lại việc hiển thị cụm
♥PEACE♥FOR♥ALL♥trong terminal dưới dạng hoạt ảnh sóng sin - Vì Base64 không có sửa lỗi nên việc chép lại khá khó; sau khi kiểm tra padding chuỗi, dấu nháy và dấu ngoặc nhọn có khớp không, tác giả so sánh và tổng hợp kết quả từ Android OCR, Tesseract và Claude
- Script sau khi giải mã kết hợp
tput,bcvà mã thoát ANSI 256 màu để tính vị trí ký tự và màu sắc theo kích thước terminal, đồng thời khôi phục con trỏ khi thoát bằngCTRL+C - Akamai giải thích đoạn mã thật ở mặt sau có liên hệ với Linux; phông chữ cũng được đính chính từ suy đoán ban đầu là Consolas thành Roboto Mono
Mã có thể chạy ở mặt sau áo thun
- Mặt trước áo thun Uniqlo x Akamai
Peace for Allcó hình trái tim trong dấu ngoặc nhọn, còn mặt sau in một khối chữ-số lớn - Nhìn gần, khối này là mã bash bắt đầu bằng shebang, có cấu trúc giải mã một Here string được mã hóa Base64 bằng
base64 --decoderồi chuyển choeval - Bề ngoài có thể trông giống “cách phát tán virus”, nhưng mục đích thực tế là hiển thị thông điệp easter egg
- Chiếc áo là sản phẩm do Akamai thiết kế nhằm ủng hộ chiến dịch Peace for All của Uniqlo
Quá trình OCR và chép lại
- Base64 không có cơ chế sửa lỗi, nên để chuyển chuỗi in trên áo thành dạng có thể chạy được cần chép lại hoàn hảo
- Chuỗi kết thúc bằng phần padding đúng như dự kiến, dấu nháy và dấu ngoặc nhọn cũng khớp, nên nhiều khả năng đây là mã hoàn chỉnh
- Ba phương pháp được dùng cùng lúc để chép lại
- OCR tích hợp trong tính năng circle-to-search của Android
- Tesseract với một số tùy chọn và điều chỉnh
- OCR và tạo bảng vị trí thông qua Claude
- Tác giả so sánh ba kết quả bằng diff để tìm các điểm không khớp, rồi xử lý thủ công phần còn lại
- Một thiết kế áo khác trong cùng dòng Uniqlo x Akamai có vẻ bị cắt từ một khối mã rộng hơn; phần imports bị cắt,
returnkết thúc thànhretu, nên ở trạng thái không thể biên dịch
Cách script bash đã giải mã hoạt động
- Khi giải mã Base64, một easter egg bash có chú thích đầy đủ xuất hiện
- Phần đầu script có thông điệp chúc mừng bằng tiếng Anh và tiếng Nhật
Congratulations! You found the easter egg! ❤️おめでとうございます!隠されたサプライズを見つけました!❤️
- Chuỗi dùng cho hoạt ảnh được lặp lại theo dạng
♥PEACE♥FOR♥ALL♥PEACE♥FOR♥ALL... - Kích thước terminal được lấy bằng
tput cols,tput lines, còn độ dài chuỗi được tính bằng${#text}của bash - Con trỏ được ẩn bằng
tput civis; khi nhậnSIGINT, script đưa con trỏ trở lại bằngtput cnorm; exit
Cách triển khai hoạt ảnh
- Vòng lặp chạy liên tục dưới dạng vòng lặp vô hạn
for (( t=0; ; t+=1 )) - Ở mỗi lần lặp, script lấy từng ký tự từ
textđể in ra - Việc tính vị trí dùng
bc -lđể tính giá trị sinangle = t * 0.2sine_value = s(angle)x = (cols / 2) + (cols / 4) * sine_value
- Giá trị
xsau khi tính được hiệu chỉnh để không vượt ra ngoài phạm vi terminal: từ 0 đếncols - 1 - Màu sắc được tính thành gradient trong bảng màu 256 màu, giữa màu cyan tương ứng với 12 và màu orange tương ứng với 208
- Việc xuất ra màn hình dùng mã thoát ANSI và
tput cupđể in ký tự đã tô màu tại vị trí chỉ định, rồi xuống dòng để đi dần xuống dưới - Kết quả là thông điệp của chiến dịch
Peace for Allxuất hiện trong terminal dưới dạng vòng lặp sóng sin liên tục
Phông chữ và giải thích thiết kế của Akamai
- Suy đoán ban đầu về phông chữ là Consolas, nhưng sau khi người dùng Hacker News ralphinus xác nhận, nó được đính chính thành Roboto Mono
- Các căn cứ cho suy đoán sai gồm số
0có nét chéo nông, số1không có serif, các đường cong tròn củaBDygvà chữ số2 - Khi ra mắt áo thun, Akamai đã giải thích thông điệp thiết kế trong thông cáo báo chí
- Màu vàng nâu sáng ám chỉ vỏ nhựa “beige box” của các máy tính thời Internet sơ khai, còn trái tim ở mặt trước thể hiện việc Internet đã được sử dụng cho những mục đích tốt đẹp trên toàn thế giới
- Đoạn mã thật ở mặt sau là một tham chiếu tới Linux; Akamai liên hệ điều này với “ngôn ngữ nguồn mở của Internet” và một ngôn ngữ chung hướng tới một thế giới an toàn hơn, kết nối hơn
- Một trường hợp khác cũng quan tâm tới chiếc áo này là bài viết của Wen Chuan Lee, và bài đó dẫn tiếp tới một bài liên quan khác
1 bình luận
Ý kiến trên Hacker News
“Một chiếc áo khác trong cùng dòng Uniqlo x Akamai có mã rõ ràng là một thiết kế chưa hoàn thiện”
Nghĩ đến cảnh phải trả hàng vì áo thun bị lỗi thật buồn cười
“Vì sao bạn trả hàng, do không vừa size hay do không thích?”
“Không, là vì có lỗi cú pháp ở dòng 37 nên nó không chạy được, và tôi lo người đi đường sẽ nghĩ tôi đang cổ xúy cho Bash scripting không an toàn”
Nếu bạn thích kiểu này thì có thể cũng sẽ thích tác phẩm của Martin Kleppe. Ví dụ như Quine Clock
https://aem1k.com/qlock/
Vài năm trước cũng đã có người đảo ngược nó về dạng không bị làm rối
https://gist.github.com/olooney/a89db3932b089925b71b68d7e9f2...
Ngoài ra còn có rất nhiều trực quan hóa ASCII tuyệt vời khác
https://aem1k.com/
Rất ấn tượng đấy, nhưng mà vẫn...
Phông chữ không phải Consolas mà là Roboto Mono
Điều lạ hơn là bản thân phông này đúng là phông monospace chuẩn, nhưng cách dàn chữ trên áo thì không phải vậy. Có kerning, đặc biệt dễ thấy ở cặp ‘Iy’, và các ký tự hẹp như ‘i’ trông như chiếm ít chiều ngang hơn. Tôi đoán họ dàn bằng công cụ kiểu “optical kerning” của InDesign
Lý do dùng phông monospace là vì nó bám lưới tốt. Nhưng ngay trong cái lưới đó vẫn có chỗ để đẩy ký tự hơi sang trái hoặc phải một chút, và biết đâu như vậy lại thành một phông monospace dễ đọc hơn. Tất nhiên, khả năng cao là cứ mỗi lần chữ bị đẩy sang trái thì phần trống bên phải sẽ to hơn, dẫn tới kết quả kinh khủng
Chiếc áo này thật sự rất hay. Có một video rất tốt trong đó chính nhà thiết kế giải thích quá trình làm ra nó. Video cũng có phần nói về quá trình cố tình làm cho OCR khó hơn: https://youtu.be/jocGLiecpjU?t=526
https://archive.org/details/1983-01-compute-magazine/page/96...
Trên Samsung S24U, tôi chỉ cần giữ nút “circle to search” ở màn hình chính để mở giao diện công cụ AI, rồi nhấn giữ vào văn bản và sao chép toàn bộ trong một lần. Tôi không biết tên chính thức của nó là gì, nhưng mất cỡ 2 giây
OCR cái này đúng là ác mộng, và là một bài benchmark hay cho những thứ tự nhận là mô hình OCR/thị giác giỏi
Tuy vậy, nếu đưa hình cho một công cụ kiểu agent có gắn mô hình thị giác tốt như Claude hay GPT đời mới, rồi bảo nó chia theo từng dòng và OCR từng dòng riêng, thì có vẻ sẽ khá dễ
Tôi cũng tò mò không biết bản thân script này trước khi bị làm rối có phải do LLM viết không. Có vẻ có khá nhiều chú thích, nhưng trong trường hợp này thì cũng ổn :)
Lời chúc mừng xuất hiện cả bằng tiếng Anh lẫn tiếng Nhật, và có một emoji trái tim. Có chủ ý tạo gradient từ xanh ngọc sang cam, nhưng dải này lại bắt đầu từ khối ANSI và kết thúc giữa chừng trong khối 256 màu, trong khi màu terminal 256 vốn không được sắp theo dạng gradient. Ngoài ra ở cuối vòng lặp cũng không có
sleep, mà nếu là LLM thì có lẽ nó đã thêm vào theo kiểu phòng thủCác ký tự tách biệt rất rõ, và không có nền cấu trúc nào gây nhiễu cho bộ đọc. Ví dụ không giống kiểu hạn sử dụng trên nắp nhôm hộp sữa chua. Cũng không có texture kiểu gần-giống-văn-bản để làm rối kết quả, và phông chữ thì sạch sẽ, tiêu chuẩn
Giờ tôi không nhớ tên người đó là ai nữa. Dạo này có quá nhiều chuyện hút hết sự chú ý
TthànhILạ là nếu cố sao chép toàn bộ chuỗi, kể cả phần hashbang, thì hiệu năng tệ hơn hẳn. Không biết bên trong nó làm gì mà lại tốt đến vậy
Gọi mã hóa base64 là làm rối mã à
Tôi đã mong đợi mấy kỹ thuật gỡ rối JS ngầu lòi, nên nói nhẹ thì là thất vọng không diễn tả nổi và cả ngày của tôi coi như hỏng
Ôi, tôi đã thấy chiếc áo đó trong cửa hàng và nói với bạn gái rằng “cái script đó đời nào chạy thật được, chắc chỉ để trang trí thôi”. Đáng lẽ tôi nên đào sâu hơn
Ổn đấy. Điều duy nhất tôi thấy tiếc ở đoạn script là giá như họ chèn
sleep 0.1
vào trong vòng lặp. Làm vậy thì khi in ra trên terminal, người ta còn có thể đọc được. Terminal hiện đại cuộn quá nhanh nên không thể nhìn thấy thông điệp lướt qua
Làm chậm xuống khoảng cập nhật 10Hz thì sẽ trông rất đẹp
Tôi thấy buồn cười khi tác giả thử đủ loại công cụ OCR, kết quả thì lúc tốt lúc dở, rồi cuối cùng lại ngồi sửa tay rất lâu bản output tốt nhất, thay vì cứ tự gõ luôn
Google OCR dùng qua Google Lens trên điện thoại cũng trích xuất khá tốt, dù không chính xác 100%. Dù vậy, chắc chắn thời gian sửa vẫn ít hơn rất nhiều so với gõ tay. Tôi không biết tác giả đã dùng gì, nhưng giá như họ chia sẻ đã thử OCR ra sao; có lẽ họ chỉ dùng một công cụ OCR đơn giản
Nếu là tôi thì tất nhiên cũng sẽ chọn OCR. Phải chuẩn bị cho lần tới gặp một chiếc áo thun Bash nữa chứ
Một đồng nghiệp cũ của tôi từng có một chiếc áo in chương trình Go, và tôi luôn thấy nó khá ngầu
[0] https://github.com/GL-Kageyama/UNIQLO_Akamai_T-shirt_Code